/*
 * 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/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/HTMLDocument.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/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/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebSecurityOrigin.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURL.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/dtoa/utils.h"
#include <map>
#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_POINT_EQ(expected, actual) \
    do { \
        EXPECT_EQ(expected.x(), actual.x()); \
        EXPECT_EQ(expected.y(), actual.y()); \
    } 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.initialize();
        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)
    {
        StyleSheetContents* styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
        styleSheet->parseString(loadResourceAsASCIIString("viewportAndroid.css"));
        RuleSet* ruleSet = RuleSet::create();
        ruleSet->addRulesFromSheet(styleSheet, MediaQueryEvaluator("screen"));

        Document* document = toLocalFrame(webViewHelper->webViewImpl()->page()->mainFrame())->document();
        document->ensureStyleResolver().viewportStyleResolver()->collectViewportRules(ruleSet, ViewportStyleResolver::UserAgentOrigin);
        document->ensureStyleResolver().viewportStyleResolver()->resolve();
    }

    static void configueCompositingWebView(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));
    }

    PassOwnPtr<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->webViewImpl()->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;
};

enum ParameterizedWebFrameTestConfig {
    Default,
    RootLayerScrolls
};

class ParameterizedWebFrameTest
    : public WebFrameTest
    , public ::testing::WithParamInterface<ParameterizedWebFrameTestConfig>
    , public FrameTestHelpers::SettingOverrider {
public:

    void overrideSettings(WebSettings* settings)
    {
        switch (GetParam()) {
        case Default:
            break;
        case RootLayerScrolls:
            settings->setRootLayerScrolls(true);
            break;
        }
    }
};

// Friendly string for gtest failure messages.
void PrintTo(ParameterizedWebFrameTestConfig config, ::std::ostream* os)
{
    switch (config) {
    case Default:
        *os << "Default";
        break;
    case RootLayerScrolls:
        *os << "RootLayerScrolls";
        break;
    }
}

INSTANTIATE_TEST_CASE_P(All, ParameterizedWebFrameTest, ::testing::Values(
    ParameterizedWebFrameTestConfig::Default,
    ParameterizedWebFrameTestConfig::RootLayerScrolls));

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

    FrameTestHelpers::WebViewHelper webViewHelper(this);
    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(this);
    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(this);
    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(this);
    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.
    toWebLocalFrameImpl(webViewHelper.webView()->mainFrame())->frame()->document()->suspendScheduledTasks();
    webViewHelper.webView()->mainFrame()->toWebLocalFrame()->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(this);
    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(this);
    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(this);
    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(this);
    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(this);

    /// 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(this);

    /// 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(this);
    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(this);
    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(this);
    webViewHelper.initializeAndLoad("about:blank");

    LocalFrame* frame = toLocalFrame(webViewHelper.webViewImpl()->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 (LayoutObject* layoutObject = document->layoutView(); layoutObject; layoutObject = layoutObject->nextInPreOrder()) {
        if (layoutObject->style()) {
            layoutObject->mutableStyleRef().setTextAutosizingMultiplier(multiplier);

            EXPECT_EQ(multiplier, layoutObject->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 (LayoutObject* layoutObject = document->layoutView(); layoutObject; layoutObject = layoutObject->nextInPreOrder()) {
        if (layoutObject->style() && layoutObject->isText()) {
            EXPECT_EQ(multiplier, layoutObject->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);

    Document* document = toLocalFrame(webViewHelper.webViewImpl()->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.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client, nullptr, configureAndroid);

    Document* document = toLocalFrame(webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, nullptr, &client, nullptr, enableViewportSettings);

    LocalFrame* mainFrame = toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame());
    Document* document = mainFrame->document();
    FrameView* frameView = webViewHelper.webViewImpl()->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 (LayoutObject* layoutObject = toLocalFrame(frame)->document()->layoutView(); layoutObject; layoutObject = layoutObject->nextInPreOrder()) {
            if (layoutObject->isText())
                EXPECT_FALSE(layoutObject->needsLayout());
        }
    }

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

    for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
        if (!frame->isLocalFrame())
            continue;
        for (LayoutObject* layoutObject = toLocalFrame(frame)->document()->layoutView(); layoutObject; layoutObject = layoutObject->nextInPreOrder()) {
            if (layoutObject->isText())
                EXPECT_TRUE(layoutObject->needsLayout());
        }
    }
}

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

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

    EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, nullptr, &client, nullptr, enableViewportSettings);

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

    EXPECT_EQ(2, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->pageScaleFactor());
    EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webViewImpl()->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.webViewImpl()->didCommitLoad(false, false);
    webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->pageScaleFactor());
    EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webViewImpl()->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.webViewImpl()->didCommitLoad(false, false);
    webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    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(this);
    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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    EXPECT_EQ(viewportHeight / 2, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
    EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webViewImpl()->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(this);
    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(this);
    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(this);
    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(this);
    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(this);
            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(this);
    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.webViewImpl()->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(this);

    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.webViewImpl()->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(this);

    webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, nullptr, &client, nullptr, configureAndroid);
    webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
    PaintLayerCompositor* compositor = webViewHelper.webViewImpl()->compositor();
    EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(0, webViewHelper.webViewImpl()->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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(0, webViewHelper.webViewImpl()->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.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
    EXPECT_EQ(viewportWidth, compositor->containerLayer()->size().width());
    EXPECT_EQ(viewportHeight, compositor->containerLayer()->size().height());

    LocalFrame* frame = webViewHelper.webViewImpl()->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(this);

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

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

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

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

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

    webViewHelper.webView()->settings()->setForceZeroLayoutHeight(false);
    EXPECT_LE(viewportHeight, webViewHelper.webViewImpl()->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.webViewImpl()->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 = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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.webViewImpl()->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);
    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;
    WebLocalFrame* localFrame = FrameTestHelpers::createLocalChild(root, "frameName", 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 = toWebLocalFrameImpl(localFrame)->frame()->document();
    EXPECT_EQ(11, childDocument->firstBodyElement()->getIntegralAttribute(HTMLNames::marginwidthAttr));
    EXPECT_EQ(22, childDocument->firstBodyElement()->getIntegralAttribute(HTMLNames::marginheightAttr));

    FrameView* frameView = toWebLocalFrameImpl(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);
    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;
    WebLocalFrame* localFrame = FrameTestHelpers::createLocalChild(root, "frameName", nullptr, nullptr, properties);

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

    Document* childDocument = toWebLocalFrameImpl(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(this);

    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.webViewImpl()->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(this);

    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.webViewImpl()->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(this);
    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.webViewImpl()->pageScaleFactor());
    EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(800, webViewHelper.webViewImpl()->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.webViewImpl()->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.webViewImpl()->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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());

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

    description.maxHeight = Length(320, blink::Fixed);
    document->setViewportDescription(description);
    webViewHelper.webView()->updateAllLifecyclePhases();
    EXPECT_EQ(800, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());

    webViewHelper.webView()->settings()->setUseWideViewport(true);
    webViewHelper.webView()->updateAllLifecyclePhases();
    EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView();
    EXPECT_FALSE(view->userInputScrollable(VerticalScrollbar));
    EXPECT_FALSE(view->userInputScrollable(HorizontalScrollbar));

    webViewHelper.webViewImpl()->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.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
    EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());

    webViewHelper.webView()->settings()->setUseWideViewport(true);
    webViewHelper.webView()->updateAllLifecyclePhases();
    EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
    webViewHelper.webViewImpl()->setPageScaleFactor(3);
    EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
    webViewHelper.webViewImpl()->setPageScaleFactor(30);
    EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
    EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    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.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr, &client, nullptr, enableViewportSettings);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    FrameView* view = webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->page()->mainFrame())->contentLayoutItem().documentRect().width());
    EXPECT_EQ(980, webViewHelper.webViewImpl()->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(this);
        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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
        EXPECT_NEAR(viewportHeight * densityDpiScaleRatio, webViewHelper.webViewImpl()->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(this);
        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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
        EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->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(this);
        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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
        EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor / pageZoom, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight / enforcedPageScaleFactor, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f);
    EXPECT_NEAR(viewportHeight, webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->pageScaleFactor(), 0.01f);
    EXPECT_NEAR(1.0f, webViewHelper.webViewImpl()->minimumPageScaleFactor(), 0.01f);
    EXPECT_NEAR(5.0f, webViewHelper.webViewImpl()->maximumPageScaleFactor(), 0.01f);
}

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(this);
        webViewHelper.initializeAndLoad(m_baseURL + url, true, nullptr, nullptr, nullptr, enableViewportSettings);
        webViewHelper.webViewImpl()->setDefaultPageScaleLimits(0.25f, 5);

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

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

INSTANTIATE_TEST_CASE_P(All, WebFrameResizeTest, ::testing::Values(
    ParameterizedWebFrameTestConfig::Default,
    ParameterizedWebFrameTestConfig::RootLayerScrolls));

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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, nullptr, &client, nullptr, enableViewportSettings);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    FrameView* view = webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->minimumPageScaleFactor());
    EXPECT_EQ(2.0f, webViewHelper.webViewImpl()->maximumPageScaleFactor());

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

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

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

    EXPECT_EQ(2.0f, webViewHelper.webViewImpl()->minimumPageScaleFactor());
    EXPECT_EQ(2.0f, webViewHelper.webViewImpl()->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;

    OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);

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

    FrameView* view = webViewHelper.webViewImpl()->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)
{
    IntSize scrollDelta = webViewImpl->fakePageScaleAnimationTargetPositionForTesting() - webViewImpl->mainFrameImpl()->frameView()->scrollPosition();
    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(this);
    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.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;

    // Test double-tap zooming into wide div.
    WebRect wideBlockBound = webViewHelper.webViewImpl()->computeBlockBound(doubleTapPointWide, false);
    webViewHelper.webViewImpl()->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.webViewImpl(), scroll, scale);

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

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

    // Test double-tap zooming into tall div.
    WebRect tallBlockBound = webViewHelper.webViewImpl()->computeBlockBound(doubleTapPointTall, false);
    webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->enableFakePageScaleAnimationForTesting(true);

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

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

    simulateDoubleTap(webViewHelper.webViewImpl(), point, scale);
    EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), point, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->computeBlockBound(point, true);
    webViewHelper.webViewImpl()->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.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->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.webViewImpl(), topPoint, scale);
    EXPECT_FLOAT_EQ(1, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);

    // If the user pinch zooms after double tap, a second double tap should zoom back to the div.
    simulateDoubleTap(webViewHelper.webViewImpl(), topPoint, scale);
    EXPECT_FLOAT_EQ(1, scale);
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 0.6f, 0);
    simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
    EXPECT_FLOAT_EQ(1, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->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.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f, 0);
    webViewHelper.webViewImpl()->animateDoubleTapZoom(topPoint);
    EXPECT_TRUE(webViewHelper.webViewImpl()->fakeDoubleTapAnimationPendingForTesting());
    simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->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.webViewImpl()->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.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
    setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(1, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(1, scale);

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

    // Zoom in to reset double_tap_zoom_in_effect flag.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f, 0);
    // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
    webViewHelper.webView()->setDefaultPageScaleLimits(0.95f, 4);
    webViewHelper.webView()->updateAllLifecyclePhases();
    doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
    setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), 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.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
    float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
    webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
    webViewHelper.webView()->updateAllLifecyclePhases();
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(legibleScale, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(legibleScale, scale);

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

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

    // Zoom in to reset double_tap_zoom_in_effect flag.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f, 0);
    // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < maximumLegibleScaleFactor
    webViewHelper.webView()->setDefaultPageScaleLimits(0.9f, 4);
    webViewHelper.webView()->updateAllLifecyclePhases();
    doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
    setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(legibleScale, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), 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.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
    webViewHelper.webViewImpl()->page()->settings().setTextAutosizingEnabled(true);
    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
    float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
    webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
    webViewHelper.webView()->updateAllLifecyclePhases();
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(legibleScale, scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
    simulateDoubleTap(webViewHelper.webViewImpl(), doubleTapPoint, scale);
    EXPECT_FLOAT_EQ(legibleScale, scale);

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

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

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

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

    FrameTestHelpers::WebViewHelper webViewHelper(this);
    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.webViewImpl()->computeBlockBound(WebPoint(9, 9), true));
    EXPECT_RECT_EQ(rectBack, blockBound);

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

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

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

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

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

    blockBound = IntRect(webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->enableFakePageScaleAnimationForTesting(true);

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

    simulateMultiTargetZoom(webViewHelper.webViewImpl(), topDiv, scale);
    EXPECT_FLOAT_EQ(1, scale);
    simulateMultiTargetZoom(webViewHelper.webViewImpl(), bottomDiv, scale);
    EXPECT_FLOAT_EQ(1, scale);
    simulateMultiTargetZoom(webViewHelper.webViewImpl(), viewportRect, scale);
    EXPECT_FLOAT_EQ(1, scale);
    webViewHelper.webViewImpl()->setPageScaleFactor(webViewHelper.webViewImpl()->minimumPageScaleFactor());
    simulateMultiTargetZoom(webViewHelper.webViewImpl(), 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.webViewImpl()->setDefaultPageScaleLimits(0.25f, 4);
    webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
    webViewHelper.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
    webViewHelper.webViewImpl()->settings()->setAutoZoomFocusedNodeToLegibleScale(true);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    float initialScale = webViewHelper.webViewImpl()->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.webViewImpl()->advanceFocus(false);
    webViewHelper.webViewImpl()->scrollFocusedEditableElementIntoRect(WebRect());
    EXPECT_EQ(webViewHelper.webViewImpl()->fakePageScaleAnimationPageScaleForTesting(), 0);

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

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

    setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), initialScale);
    ASSERT_EQ(initialScale, webViewHelper.webViewImpl()->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.webViewImpl()->scrollFocusedEditableElementIntoRect(WebRect());
    EXPECT_GT(webViewHelper.webViewImpl()->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.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
    webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 4);

    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), 1);
    WebRect rect, caret;
    webViewHelper.webViewImpl()->selectionBounds(caret, rect);

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

    float scale;
    IntPoint scroll;
    bool needAnimation;
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), initialScale);
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), initialScale);
    // Move focus to edit box with text.
    webViewHelper.webView()->advanceFocus(false);
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl(), scroll, withinToleranceScale);
    // Move focus back to the second edit box.
    webViewHelper.webView()->advanceFocus(false);
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), 1);
    WebRect rect, caret;
    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), newScale);

    float scale;
    IntPoint scroll;
    bool needAnimation;
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(hScroll, 0), newScale);
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
    webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 4);

    webViewHelper.webViewImpl()->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.webViewImpl(), WebPoint(0, 0), initialScale);

    float scale;
    IntPoint scroll;
    bool needAnimation;
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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.webViewImpl(), scroll, scale);

    // Select the first textbox.
    webViewHelper.webView()->advanceFocus(true);
    WebRect rect, caret;
    webViewHelper.webViewImpl()->selectionBounds(caret, rect);
    webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "sometext.html");
    webViewHelper.resize(WebSize(640, 480));

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

    WebRect baseRect;
    WebRect extentRect;

    WebFrame* mainFrame = webViewHelper.webViewImpl()->mainFrame();
    size_t ix = mainFrame->characterIndexForPoint(WebPoint(320, 388));

    EXPECT_EQ(2ul, ix);
}

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

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

    WebFrame* mainFrame = webViewHelper.webViewImpl()->mainFrame();
    mainFrame->executeScript(WebScriptSource("selectRange();"));

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

    WebFloatPoint visualOffset(100, 130);
    float scale = 2;
    webViewHelper.webViewImpl()->setPageScaleFactor(scale);
    webViewHelper.webViewImpl()->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(this);
    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.webViewImpl()->mainFrame()->setScrollOffset(WebSize(pageWidth / 4, pageHeight / 4));
    webViewHelper.webViewImpl()->setPageScaleFactor(pageScaleFactor);

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

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

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

    // Reload the page while ignoring the cache. State should not be propagated.
    webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + thirdURL), WebFrameLoadType::ReloadBypassingCache);
    FrameTestHelpers::pumpPendingRequestsForFrameToLoad(webViewHelper.webViewImpl()->mainFrame());
    EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().width);
    EXPECT_EQ(0, webViewHelper.webViewImpl()->mainFrame()->scrollOffset().height);
    EXPECT_EQ(1.0f, webViewHelper.webViewImpl()->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(this);
    webViewHelper.initialize();
    WebURLRequest request;
    request.initialize();
    request.setURL(toKURL(m_baseURL + "fixed_layout.html"));
    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(this);
    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(this);
    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"));
    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(this);
    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.webViewImpl()->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<OwnPtr<Notification>> createNotifications;
    Vector<OwnPtr<Notification>> releaseNotifications;

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

    void willReleaseScriptContext(WebLocalFrame* frame, v8::Local<v8::Context> context, int worldId) override
    {
        releaseNotifications.append(adoptPtr(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(this);
    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(this);
    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(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find.html");
    ASSERT_TRUE(webViewHelper.webView()->mainFrame()->isWebLocalFrame());
    webViewHelper.webView()->setFocus(true);
    WebLocalFrame* frame = webViewHelper.webView()->mainFrame()->toWebLocalFrame();
    const int findIdentifier = 12345;
    WebFindOptions options;

    // Find in a <div> element.
    EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar1"), options, false, 0));
    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, 0));
    // 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, 0));
    // 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, 0));
    // 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, 0));
    // 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(this);
    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(this);
    webViewHelper.initializeAndLoad("about:blank", true);
    WebFrame* frame = webViewHelper.webView()->mainFrame();

    // 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->toWebLocalFrame()).utf8();

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

    EXPECT_EQ(html, WebFrameContentDumper::dumpAsMarkup(frame->toWebLocalFrame()).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(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find_in_page_frame.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setMaximumLegibleScale(1.f);
    webViewHelper.webView()->updateAllLifecyclePhases();
    webViewHelper.webView()->setFocus(true);
    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 = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false, 0));

    mainFrame->resetMatchCount();

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

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

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

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

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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, 0));
    mainFrame->resetMatchCount();

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

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

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

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

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

    mainFrame->resetMatchCount();

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

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

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false)) {
        webViewHelper.webView()->setFocusedFrame(frame);
        EXPECT_TRUE(frame->toWebLocalFrame()->find(kFindIdentifier, searchText, options, false, 0));
    }

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

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

    mainFrame->resetMatchCount();

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

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

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false)) {
        webViewHelper.webView()->setFocusedFrame(frame);
        EXPECT_TRUE(frame->toWebLocalFrame()->find(kFindIdentifier, searchText, options, false, 0));
    }

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

    mainFrame->resetMatchCount();

    for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
        frame->toWebLocalFrame()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find_in_generated_frame.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

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

    // 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, 0));

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

    mainFrame->resetMatchCount();
}

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

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

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

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

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

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

    // Get the tickmarks for the original find request.
    FrameView* frameView = webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "find.html", true, &client);
    webViewHelper.resize(WebSize(640, 480));
    webViewHelper.webView()->setFocus(true);
    runPendingTasks();

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

    frame->resetMatchCount();
    frame->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, 0, &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, 0, &activeNow));
    EXPECT_TRUE(activeNow);

    // Find in the inserted text node.
    EXPECT_TRUE(frame->find(findIdentifier, searchText, options, false, 0, &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->selectionAsText().utf8();
}

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

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

    FrameTestHelpers::WebViewHelper webViewHelper(this);
    initializeTextSelectionWebView(m_baseURL + "select_range_basic.html", &webViewHelper);
    frame = webViewHelper.webView()->mainFrame();
    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()->mainFrame();
    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(this);
    initializeTextSelectionWebView(m_baseURL + "select_range_iframe.html", &webViewHelper);
    frame = webViewHelper.webView()->mainFrame();
    WebFrame* subframe = frame->firstChild();
    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)
{
    WebFrame* 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(this);
    initializeTextSelectionWebView(m_baseURL + "select_range_div_editable.html", &webViewHelper);
    frame = webViewHelper.webView()->mainFrame();
    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()->mainFrame();

    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)
{
    WebFrame* 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(this);
    initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html", &webViewHelper);
    frame = webViewHelper.webView()->mainFrame();
    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()->mainFrame();

    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(this);
    initializeTextSelectionWebView(m_baseURL + "text_selection.html", &webViewHelper);
    WebFrame* frame = webViewHelper.webView()->mainFrame();

    // 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(this);
    initializeTextSelectionWebView(m_baseURL + "text_selection.html", &webViewHelper);
    WebFrame* frame = webViewHelper.webView()->mainFrame();

    // 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(this);
    initializeTextSelectionWebView(m_baseURL + "move_range_selection_extent.html", &webViewHelper);
    frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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(this);
    initializeTextSelectionWebView(m_baseURL + "move_range_selection_extent.html", &webViewHelper);
    frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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(this);
    initializeTextSelectionWebView(m_baseURL + "move_range_selection_extent_input_field.html", &webViewHelper);
    frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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(this);
    initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html", &webViewHelper);
    WebLocalFrameImpl* mainFrame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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 = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    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(this);
    initializeTextSelectionWebView(m_baseURL + "move_caret.html", &webViewHelper);
    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());

    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(this);
    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 = adoptPtr(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;
    OwnPtr<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()->mainFrame()->toWebLocalFrame()->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(this);
    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.
    WebFrame* frame = webViewHelper.webView()->mainFrame();
    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.webViewImpl()->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()->mainFrame();
    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(this);
    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(this);
    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(this);
    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(this);
    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.webViewImpl();
    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_POINT_EQ(IntPoint(0, 400), frame->view()->scrollPosition());

    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_FLOAT_POINT_EQ(FloatPoint(0, 0), visualViewport.location());

    // 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_FLOAT_POINT_EQ(FloatPoint(0, 200), visualViewport.location());

    // 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(this);
    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(this);
    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(this);
    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.initialize();
    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(this);
    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(this);
    webViewHelper.initialize(false, &webFrameClient);

    EXPECT_FALSE(webFrameClient.m_didLoad);
    EXPECT_EQ(1, webFrameClient.m_numBodies); // The empty document that a new frame starts with triggers this.
}

TEST_P(ParameterizedWebFrameTest, MoveCaretSelectionTowardsWindowPointWithNoSelection)
{
    FrameTestHelpers::WebViewHelper webViewHelper(this);
    webViewHelper.initializeAndLoad("about:blank", true);
    WebFrame* frame = webViewHelper.webView()->mainFrame();

    // This test passes if this doesn't crash.
    frame->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
    SpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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::fromDocumentRange(frame, 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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
    SpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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::fromDocumentRange(frame, 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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
    SpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    LocalFrame* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame())->frame();
    Document* document = frame->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

    static const uint32_t kHash = 42;
    SpellCheckClient spellcheck(kHash);
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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 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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

    StubbornSpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
    webViewHelper.webView()->setSpellCheckClient(0);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

    StubbornSpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);

    element->focus();
    NonThrowableExceptionState exceptionState;
    document->execCommand("InsertText", false, "welcome ", exceptionState);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

    StubbornSpellCheckClient spellcheck;
    webViewHelper.webView()->setSpellCheckClient(&spellcheck);

    WebLocalFrameImpl* frame = toWebLocalFrameImpl(webViewHelper.webView()->mainFrame());
    Document* document = frame->frame()->document();
    Element* element = document->getElementById("data");

    webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
    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()
    {
        EXPECT_TRUE(!m_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(this);
    webViewHelper.initialize(true, &webFrameClient, &webViewClient);
    runPendingTasks();
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Create another window that will try to access it.
    FrameTestHelpers::WebViewHelper newWebViewHelper(this);
    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(this);
    webViewHelper.initialize(true, &webFrameClient, &webViewClient);
    runPendingTasks();
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Create another window that will try to access it.
    FrameTestHelpers::WebViewHelper newWebViewHelper(this);
    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(this);
    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(this);
    webViewHelper.initialize(true, &webFrameClient, &webViewClient);
    runPendingTasks();
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Create another window that will try to access it.
    FrameTestHelpers::WebViewHelper newWebViewHelper(this);
    WebView* newView = newWebViewHelper.initializeWithOpener(webViewHelper.webView()->mainFrame(), true);
    runPendingTasks();
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Access the initial document by modifying the body. We normally set a
    // timer to notify the client.
    newView->mainFrame()->executeScript(
        WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Make sure that a modal dialog forces us to notify right away.
    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(this);
    webViewHelper.initialize(true, &webFrameClient, &webViewClient);
    runPendingTasks();
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Create another window that will try to access it.
    FrameTestHelpers::WebViewHelper newWebViewHelper(this);
    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. We normally set a
    // timer to notify the client.
    newView->mainFrame()->executeScript(
        WebScriptSource("window.opener.document.write('Modified'); window.opener.document.close();"));
    EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

    // Make sure that a modal dialog forces us to notify right away.
    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_P(ParameterizedWebFrameTest, 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.webViewImpl()->mainFrameImpl();
    DocumentLoader::InitialScrollState& initialScrollState =
        frameImpl->frame()->loader().documentLoader()->initialScrollState();

    EXPECT_FALSE(client.wasFrameScrolled());
    EXPECT_FALSE(initialScrollState.wasScrolledByUser);

    // Do a compositor scroll, verify that this is counted as a user scroll.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(0, 1), WebFloatSize(), 1.7f, 0);
    EXPECT_TRUE(client.wasFrameScrolled());
    EXPECT_TRUE(initialScrollState.wasScrolledByUser);

    client.reset();
    initialScrollState.wasScrolledByUser = false;

    // The page scale 1.0f and scroll.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(0, 1), 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.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f, 0);
    EXPECT_FALSE(client.wasFrameScrolled());
    EXPECT_FALSE(initialScrollState.wasScrolledByUser);
    client.reset();

    // Non zero page scale and scroll.
    webViewHelper.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(9, 13), 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.initialize();
    redirectResponse.setMIMEType("text/html");
    redirectResponse.setHTTPStatusCode(302);
    redirectResponse.setHTTPHeaderField("Location", redirect);
    Platform::current()->getURLLoaderMockFactory()->registerURL(testURL, redirectResponse, filePath);

    WebURLResponse finalResponse;
    finalResponse.initialize();
    finalResponse.setMIMEType("text/html");
    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, finalResponse, filePath);

    FrameTestHelpers::WebViewHelper webViewHelper(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true, &client);

    Document* document = toLocalFrame(webViewHelper.webViewImpl()->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());
    FrameLoadRequest frameRequest(document, ResourceRequest(destination));
    frameRequest.setTriggeringEvent(event);
    toLocalFrame(webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "ctrl_click.html", true, &webFrameClient, &webViewClient);

    Document* document = toLocalFrame(webViewHelper.webViewImpl()->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());
    FrameLoadRequest frameRequest(document, ResourceRequest(destination));
    frameRequest.setTriggeringEvent(event);
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    toLocalFrame(webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true);
    WebFrame* frame = webViewHelper.webView()->mainFrame();
    const FrameLoader& mainFrameLoader = webViewHelper.webViewImpl()->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "page_with_blank_iframe.html", true);
    WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
    const FrameLoader& mainFrameLoader = webViewHelper.webViewImpl()->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->toWebLocalFrame()->requestFromHistoryItem(item, WebCachePolicy::UseProtocolCachePolicy);
    mainFrame->toWebLocalFrame()->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(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true);
    WebFrame* frame = webViewHelper.webView()->mainFrame();
    const FrameLoader& mainFrameLoader = webViewHelper.webViewImpl()->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 WebFrame* createChildFrame(WebLocalFrame* parent, WebTreeScopeType scope, const WebString&, const WebString&, WebSandboxFlags, const WebFrameOwnerProperties& frameOwnerProperties)
    {
        DCHECK(m_childClient);
        m_childFrameCreationCount++;
        WebFrame* 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* frame, unsigned, WebURLRequest& request, const WebURLResponse&) 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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, &mainClient);

    WebLocalFrameImpl* mainFrame = webViewHelper.webViewImpl()->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, unsigned, WebURLRequest&, const WebURLResponse&)
    {
        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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "navigate_to_same.html", true, &client);
    EXPECT_FALSE(client.frameLoadTypeReloadMainResourceSeen());

    FrameLoadRequest frameRequest(0, ResourceRequest(toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->document()->url()));
    toLocalFrame(webViewHelper.webViewImpl()->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* frame, unsigned, WebURLRequest& request, const WebURLResponse&)
    {
        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(this);
    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(this);
    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(this);
    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(this);
    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(this);
    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(this);
    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");
    OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(), nullptr, &configueCompositingWebView);

    webViewHelper.resize(WebSize(100, 100));
    FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "non-scrollable.html");

    PaintLayerCompositor* compositor =  webViewHelper.webViewImpl()->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(this);
    webViewHelper.initialize();
    WebFrame* frame = webViewHelper.webView()->mainFrame();
    const FrameLoader& mainFrameLoader = webViewHelper.webViewImpl()->mainFrameImpl()->frame()->loader();
    WebURLRequest request;
    request.initialize();
    request.setURL(toKURL(url));
    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) { }

    WebFrame* createChildFrame(WebLocalFrame* parent, WebTreeScopeType scope, const WebString& frameName, const WebString& frameUniqueName, WebSandboxFlags sandboxFlags, const WebFrameOwnerProperties& frameOwnerProperties) override
    {
        ++m_callCount;
        return 0;
    }

    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(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "fixed-position-in-fixed-viewport.html", true, nullptr, nullptr, nullptr, enableViewportSettings);

    WebView* webView = webViewHelper.webView();
    webViewHelper.resize(WebSize(100, 100));

    Document* document = toWebLocalFrameImpl(webView->mainFrame())->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(this);
    webViewHelper.initializeAndLoad("about:blank");
    webViewHelper.resize(WebSize(200, 200));
    webViewHelper.webViewImpl()->updateAllLifecyclePhases();

    FrameView* frameView = webViewHelper.webViewImpl()->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.webViewImpl();
    FrameView* frameView = webViewHelper.webViewImpl()->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_POINT_EQ(IntPoint(0, 1900), IntPoint(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_POINT_EQ(IntPoint(0, 1920), frameView->maximumScrollPosition());

    // 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_POINT_EQ(IntPoint(0, 1940), IntPoint(frameView->scrollOffset()));

    // Hide until there's 10px showing.
    webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f, -30.0f / topControlsHeight);
    EXPECT_POINT_EQ(IntPoint(0, 1910), frameView->maximumScrollPosition());

    // 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_POINT_EQ(IntPoint(0, 1940), frameView->maximumScrollPosition());

    // Now simulate hiding.
    webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f, -10.0f / topControlsHeight);
    EXPECT_POINT_EQ(IntPoint(0, 1930), frameView->maximumScrollPosition());

    // 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_POINT_EQ(IntPoint(0, 1900), frameView->maximumScrollPosition());

    // 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_POINT_EQ(IntPoint(0, 1901), frameView->maximumScrollPosition());

    webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f, 2.0f / topControlsHeight);
    EXPECT_POINT_EQ(IntPoint(0, 1903), frameView->maximumScrollPosition());
}

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.webViewImpl()->mainFrameImpl()->frameView();
    EXPECT_LT(frameView->maximumScrollPosition().x(), 0);
}

TEST_P(ParameterizedWebFrameTest, FullscreenLayerSize)
{
    FakeCompositingWebViewClient client;
    registerMockedHttpURLLoad("fullscreen_div.html");
    FrameTestHelpers::WebViewHelper webViewHelper(this);
    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 = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Element* divFullscreen = document->getElementById("div1");
    Fullscreen::from(*document).requestFullscreen(*divFullscreen, Fullscreen::PrefixedRequest);
    webViewImpl->didEnterFullScreen();
    webViewImpl->updateAllLifecyclePhases();
    ASSERT_TRUE(Fullscreen::isFullScreen(*document));

    // 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 = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Element* divFullscreen = document->getElementById("div1");
    Fullscreen::from(*document).requestFullscreen(*divFullscreen, Fullscreen::PrefixedRequest);
    webViewImpl->didEnterFullScreen();
    webViewImpl->updateAllLifecyclePhases();

    // Verify that the viewports are nonscrollable.
    ASSERT_TRUE(Fullscreen::isFullScreen(*document));
    FrameView* frameView = webViewHelper.webViewImpl()->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();
    ASSERT_FALSE(Fullscreen::isFullScreen(*document));
    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(this);
    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 = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Fullscreen::from(*document).requestFullscreen(*document->documentElement(), Fullscreen::PrefixedRequest);
    webViewImpl->didEnterFullScreen();
    webViewImpl->updateAllLifecyclePhases();

    // Verify that the main frame is still scrollable.
    ASSERT_TRUE(Fullscreen::isFullScreen(*document));
    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(this);
    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(DefinitelyProcessingUserGesture);
    Element* divFullscreen = document->getElementById("div1");
    Fullscreen::from(*document).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(this);
    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.webViewImpl()->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 = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Fullscreen::from(*document).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(this);
    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.webViewImpl()->mainFrameImpl()->frameView()->layoutViewItem();
    Document* document = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Fullscreen::from(*document).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(this);
    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.webViewImpl()->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 = toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
        UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
        Fullscreen::from(*document).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(this);
    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 =
        toWebLocalFrameImpl(webViewImpl->mainFrame())->frame()->document();
    UserGestureIndicator gesture(DefinitelyProcessingUserGesture);
    Fullscreen::from(*document).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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "percent-height-descendants.html");

    WebView* webView = webViewHelper.webView();
    webViewHelper.resize(WebSize(800, 800));
    webView->updateAllLifecyclePhases();

    Document* document = toWebLocalFrameImpl(webView->mainFrame())->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(this);
    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(this);
    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(this);
    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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
    Document* document = toWebLocalFrameImpl(webViewHelper.webViewImpl()->mainFrame())->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
    Document* document = toWebLocalFrameImpl(webViewHelper.webViewImpl()->mainFrame())->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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
    Document* document = toWebLocalFrameImpl(webViewHelper.webViewImpl()->mainFrame())->frame()->document();

    Resource* resource = fetchManifest(document, toKURL(m_notBaseURL + "link-manifest-fetch.json"));

    EXPECT_EQ(0, resource); // Fetching resource wasn't allowed.
}

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(this);
    webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
    Document* document = toWebLocalFrameImpl(webViewHelper.webViewImpl()->mainFrame())->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(this);
    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(this);
    OwnPtr<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(this);
    OwnPtr<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(this);
    OwnPtr<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(this);
    OwnPtr<DragImage> dragImage = nodeImageTestSetup(&webViewHelper, std::string("case-inlineblock"));
    EXPECT_TRUE(dragImage);

    nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestFloatLeft)
{
    FrameTestHelpers::WebViewHelper webViewHelper(this);
    OwnPtr<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(this);
    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(this);
    ThemeColorTestWebFrameClient client;
    webViewHelper.initializeAndLoad(m_baseURL + "theme_color_test.html", true, &client);
    EXPECT_TRUE(client.didNotify());
    WebLocalFrameImpl* frame = webViewHelper.webViewImpl()->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);
    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);
    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;
    WebRemoteFrame* remoteFrame = WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
    targetFrame->swap(remoteFrame);
    ASSERT_TRUE(mainFrame()->firstChild());
    ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);
    EXPECT_EQ(uniqueName.utf8(), WebString(toWebRemoteFrameImpl(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.
    localFrame->setName("");
    WebString uniqueName2 = localFrame->uniqueName();
    EXPECT_EQ("<!--framePath //<!--frame2-->-->", uniqueName2.utf8());

    FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient2;
    WebRemoteFrame* remoteFrame2 = WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient2);
    localFrame->swap(remoteFrame2);
    ASSERT_TRUE(mainFrame()->firstChild());
    ASSERT_EQ(mainFrame()->firstChild(), remoteFrame2);
    EXPECT_EQ(uniqueName2.utf8(), WebString(toWebRemoteFrameImpl(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);
    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);
    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);
    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);
    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 GestureEventTestWebViewClient : public FrameTestHelpers::TestWebViewClient {
public:
    GestureEventTestWebViewClient() : 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);

    FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
    view->setMainFrame(remoteClient.frame());

    WebLocalFrame* childFrame = FrameTestHelpers::createLocalChild(view->mainFrame()->toWebRemoteFrame());

    GestureEventTestWebViewClient childViewClient;
    WebFrameWidget* widget = WebFrameWidget::create(childViewClient.widgetClient(), childFrame);

    view->resize(WebSize(1000, 1000));

    widget->handleInputEvent(fatTap(20, 20));
    EXPECT_TRUE(childViewClient.didHandleGestureEvent());

    widget->close();
    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(this);
    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.webViewImpl()->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);
    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(this);
    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(this);
    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("opener.frames[1].location.href='data:text/html,foo'"));
    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();
}

class DeviceEmulationTest : public ParameterizedWebFrameTest {
protected:
    DeviceEmulationTest()
        : m_webViewHelper(this)
    {
        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()->mainFrame()->toWebLocalFrame()->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::Values(
    ParameterizedWebFrameTestConfig::Default,
    ParameterizedWebFrameTestConfig::RootLayerScrolls));

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);
    view->setMainFrame(remoteClient.frame());
    WebRemoteFrame* parent = view->mainFrame()->toWebRemoteFrame();

    WebLocalFrame* secondFrame(FrameTestHelpers::createLocalChild(parent, "name2"));
    WebLocalFrame* fourthFrame(FrameTestHelpers::createLocalChild(parent, "name4", nullptr, secondFrame));
    WebLocalFrame* thirdFrame(FrameTestHelpers::createLocalChild(parent, "name3", 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);
    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);
    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);
    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);
    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();
}

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->webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
    }

    void ScrollUpdate(FrameTestHelpers::WebViewHelper* webViewHelper, float deltaX, float deltaY)
    {
        webViewHelper->webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, deltaX, deltaY));
    }

    void ScrollEnd(FrameTestHelpers::WebViewHelper* webViewHelper)
    {
        webViewHelper->webViewImpl()->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");
    WebView* webView = webViewHelper.webView();
    Document* document = toWebLocalFrameImpl(webView->mainFrame())->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()->mainFrame()->toWebLocalFrame();
    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()->mainFrame()->toWebLocalFrame();
    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()->mainFrame()->toWebLocalFrame();
    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()->mainFrame()->toWebLocalFrame();
    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()));
}

static void setSecurityOrigin(WebFrame* frame, PassRefPtr<SecurityOrigin> securityOrigin)
{
    Document* document = frame->document();
    document->setSecurityOrigin(securityOrigin);
}

TEST_F(WebFrameTest, CanHaveSecureChild)
{
    FrameTestHelpers::WebViewHelper helper;
    FrameTestHelpers::TestWebFrameClient client;
    helper.initialize(true, &client, nullptr, nullptr);
    WebFrame* mainFrame = helper.webView()->mainFrame();
    RefPtr<SecurityOrigin> secureOrigin = SecurityOrigin::createFromString("https://example.com");
    RefPtr<SecurityOrigin> insecureOrigin = SecurityOrigin::createFromString("http://example.com");

    // Secure frame.
    setSecurityOrigin(mainFrame, secureOrigin);
    ASSERT_TRUE(mainFrame->canHaveSecureChild());

    // Insecure frame.
    setSecurityOrigin(mainFrame, insecureOrigin);
    ASSERT_FALSE(mainFrame->canHaveSecureChild());

    // Create a chain of frames.
    FrameTestHelpers::loadFrame(mainFrame, "data:text/html,<iframe></iframe>");
    WebFrame* childFrame = mainFrame->firstChild();
    FrameTestHelpers::loadFrame(childFrame, "data:text/html,<iframe></iframe>");
    WebFrame* grandchildFrame = childFrame->firstChild();

    // Secure -> insecure -> secure frame.
    setSecurityOrigin(mainFrame, secureOrigin);
    setSecurityOrigin(childFrame, insecureOrigin);
    setSecurityOrigin(grandchildFrame, secureOrigin);
    ASSERT_TRUE(mainFrame->canHaveSecureChild());
    ASSERT_FALSE(childFrame->canHaveSecureChild());
    ASSERT_FALSE(grandchildFrame->canHaveSecureChild());

    // A document in an insecure context can be considered secure if it has a
    // scheme that bypasses the secure context check. But the exception doesn't
    // apply to children of that document's frame.
    SchemeRegistry::registerURLSchemeBypassingSecureContextCheck("very-special-scheme");
    SchemeRegistry::registerURLSchemeAsSecure("very-special-scheme");
    RefPtr<SecurityOrigin> specialOrigin = SecurityOrigin::createFromString("very-special-scheme://example.com");

    setSecurityOrigin(mainFrame, insecureOrigin);
    setSecurityOrigin(childFrame, specialOrigin);
    setSecurityOrigin(grandchildFrame, secureOrigin);
    ASSERT_FALSE(mainFrame->canHaveSecureChild());
    ASSERT_FALSE(childFrame->canHaveSecureChild());
    ASSERT_FALSE(grandchildFrame->canHaveSecureChild());
    Document* mainDocument = mainFrame->document();
    Document* childDocument = childFrame->document();
    Document* grandchildDocument = grandchildFrame->document();
    ASSERT_FALSE(mainDocument->isSecureContext());
    ASSERT_TRUE(childDocument->isSecureContext());
    ASSERT_FALSE(grandchildDocument->isSecureContext());
}

} // namespace blink
