This source file includes following definitions.
- initializeLayerTreeView
- layerTreeView
- enterFullScreen
- m_chromeURL
- registerMockedHttpURLLoad
- registerMockedChromeURLLoad
- applyViewportStyleOverride
- configueCompositingWebView
- initializeTextSelectionWebView
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- didMatchCSS
- doc
- updateCount
- matchedSelectors
- loadHTML
- executeScript
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- screenInfo
- enableViewportSettings
- TEST_F
- checkOrSetTextAutosizingMultiplier
- setTextAutosizingMultiplier
- checkTextAutosizingMultiplier
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- computeRelativeOffset
- testResizeYieldsCorrectScrollAndScale
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- setScaleAndScrollAndLayout
- TEST_F
- simulatePageScale
- simulateMultiTargetZoom
- simulateDoubleTap
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- decidePolicyForNavigation
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- reset
- didCreateScriptContext
- willReleaseScriptContext
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- didCreateScriptContext
- TEST_F
- m_count
- reportFindInPageMatchCount
- findResultsAreReady
- count
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- topLeft
- bottomRightMinusOne
- elementBounds
- selectionAsString
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- computeOffset
- TEST_F
- TEST_F
- TEST_F
- didTapMultipleTargets
- triggered
- resetTriggered
- fatTap
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- didFailProvisionalLoad
- didCommitProvisionalLoad
- commitCalled
- TEST_F
- m_didLoad
- didCommitProvisionalLoad
- didCreateDocumentElement
- willInsertBody
- TEST_F
- TEST_F
- TEST_F
- m_hash
- requestCheckingOfText
- numberOfTimesChecked
- TEST_F
- TEST_F
- TEST_F
- requestCheckingOfText
- kickNoResults
- kick
- kickGrammar
- kickInvisibleSpellcheck
- kick
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- didAccessInitialDocument
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- reset
- wasUserScroll
- wasProgrammaticScroll
- didChangeScrollOffset
- TEST_F
- TEST_F
- TEST_F
- didNavigateWithinPage
- TEST_F
- createView
- decidePolicyForNavigation
- decidePolicyCallCount
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- m_childFrameCreationCount
- setChildWebFrameClient
- cachePolicy
- willSendRequestCallCount
- childFrameCreationCount
- createChildFrame
- frameDetached
- willSendRequest
- TEST_F
- TEST_F
- willSendRequest
- frameLoadTypeSameSeen
- TEST_F
- TEST_F
- m_differentDocumentStartCount
- didStartLoading
- didStopLoading
- startLoadingCount
- stopLoadingCount
- differentDocumentStartCount
- TEST_F
- didStartProvisionalLoad
- replacesCurrentHistoryItem
- frame
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- createChildFrame
- frameDetached
- callCount
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "config.h"
#include "WebFrame.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <v8.h>
#include "FrameTestHelpers.h"
#include "RuntimeEnabledFeatures.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "URLTestHelpers.h"
#include "UserAgentStyleSheets.h"
#include "WebDataSource.h"
#include "WebDocument.h"
#include "WebFindOptions.h"
#include "WebFormElement.h"
#include "WebFrameClient.h"
#include "WebFrameImpl.h"
#include "WebHistoryItem.h"
#include "WebRange.h"
#include "WebScriptSource.h"
#include "WebSearchableFormData.h"
#include "WebSecurityOrigin.h"
#include "WebSecurityPolicy.h"
#include "WebSettings.h"
#include "WebSpellCheckClient.h"
#include "WebTextCheckingCompletion.h"
#include "WebTextCheckingResult.h"
#include "WebViewClient.h"
#include "WebViewImpl.h"
#include "core/clipboard/Clipboard.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/ViewportStyleResolver.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/Range.h"
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/SpellChecker.h"
#include "core/editing/VisiblePosition.h"
#include "core/events/MouseEvent.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLFormElement.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/page/EventHandler.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/TextAutosizer.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/FloatRect.h"
#include "platform/network/ResourceError.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "public/platform/Platform.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLResponse.h"
#include "public/platform/WebUnitTestSupport.h"
#include "wtf/Forward.h"
#include "wtf/dtoa/utils.h"
#include <map>
using namespace blink;
using WebCore::Document;
using WebCore::DocumentMarker;
using WebCore::Element;
using WebCore::FloatRect;
using WebCore::HitTestRequest;
using WebCore::Range;
using blink::URLTestHelpers::toKURL;
using blink::FrameTestHelpers::runPendingTasks;
namespace {
const int touchPointPadding = 32;
#define EXPECT_EQ_RECT(a, b) \
EXPECT_EQ(a.x(), b.x()); \
EXPECT_EQ(a.y(), b.y()); \
EXPECT_EQ(a.width(), b.width()); \
EXPECT_EQ(a.height(), b.height());
class FakeCompositingWebViewClient : public WebViewClient {
public:
virtual ~FakeCompositingWebViewClient()
{
}
virtual void initializeLayerTreeView() OVERRIDE
{
m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest));
ASSERT(m_layerTreeView);
}
virtual WebLayerTreeView* layerTreeView() OVERRIDE
{
return m_layerTreeView.get();
}
virtual bool enterFullScreen() OVERRIDE { return true; }
private:
OwnPtr<WebLayerTreeView> m_layerTreeView;
};
class WebFrameTest : public testing::Test {
protected:
WebFrameTest()
: m_baseURL("http://www.test.com/")
, m_chromeURL("chrome://")
{
}
virtual ~WebFrameTest()
{
Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
}
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 applyViewportStyleOverride(FrameTestHelpers::WebViewHelper* webViewHelper)
{
RefPtrWillBeRawPtr<WebCore::StyleSheetContents> styleSheet = WebCore::StyleSheetContents::create(WebCore::CSSParserContext(WebCore::UASheetMode, 0));
styleSheet->parseString(String(WebCore::viewportAndroidUserAgentStyleSheet, sizeof(WebCore::viewportAndroidUserAgentStyleSheet)));
OwnPtrWillBeRawPtr<WebCore::RuleSet> ruleSet = WebCore::RuleSet::create();
ruleSet->addRulesFromSheet(styleSheet.get(), WebCore::MediaQueryEvaluator("screen"));
Document* document = webViewHelper->webViewImpl()->page()->mainFrame()->document();
document->ensureStyleResolver().viewportStyleResolver()->collectViewportRules(ruleSet.get(), WebCore::ViewportStyleResolver::UserAgentOrigin);
document->ensureStyleResolver().viewportStyleResolver()->resolve();
}
static void configueCompositingWebView(WebSettings* settings)
{
settings->setForceCompositingMode(true);
settings->setAcceleratedCompositingEnabled(true);
settings->setAcceleratedCompositingForFixedPositionEnabled(true);
settings->setAcceleratedCompositingForOverflowScrollEnabled(true);
settings->setAcceleratedCompositingForScrollableFramesEnabled(true);
settings->setCompositedScrollingForFramesEnabled(true);
}
void initializeTextSelectionWebView(const std::string& url, FrameTestHelpers::WebViewHelper* webViewHelper)
{
webViewHelper->initializeAndLoad(url, true);
webViewHelper->webView()->settings()->setDefaultFontSize(12);
webViewHelper->webView()->resize(WebSize(640, 480));
}
std::string m_baseURL;
std::string m_chromeURL;
};
class UseMockScrollbarSettings {
public:
UseMockScrollbarSettings()
{
WebCore::Settings::setMockScrollbarsEnabled(true);
WebCore::RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true);
EXPECT_TRUE(WebCore::ScrollbarTheme::theme()->usesOverlayScrollbars());
}
~UseMockScrollbarSettings()
{
WebCore::Settings::setMockScrollbarsEnabled(false);
WebCore::RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(false);
}
};
TEST_F(WebFrameTest, ContentText)
{
registerMockedHttpURLLoad("iframes_test.html");
registerMockedHttpURLLoad("visible_iframe.html");
registerMockedHttpURLLoad("invisible_iframe.html");
registerMockedHttpURLLoad("zero_sized_iframe.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html");
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(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_F(WebFrameTest, FrameForEnteredContext)
{
registerMockedHttpURLLoad("iframes_test.html");
registerMockedHttpURLLoad("visible_iframe.html");
registerMockedHttpURLLoad("invisible_iframe.html");
registerMockedHttpURLLoad("zero_sized_iframe.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html", true);
v8::HandleScope scope(v8::Isolate::GetCurrent());
EXPECT_EQ(webViewHelper.webView()->mainFrame(), WebFrame::frameForContext(webViewHelper.webView()->mainFrame()->mainWorldScriptContext()));
EXPECT_EQ(webViewHelper.webView()->mainFrame()->firstChild(), WebFrame::frameForContext(webViewHelper.webView()->mainFrame()->firstChild()->mainWorldScriptContext()));
}
TEST_F(WebFrameTest, FormWithNullFrame)
{
registerMockedHttpURLLoad("form.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "form.html");
WebVector<WebFormElement> forms;
webViewHelper.webView()->mainFrame()->document().forms(forms);
webViewHelper.reset();
EXPECT_EQ(forms.size(), 1U);
WebSearchableFormData searchableDataForm(forms[0]);
}
TEST_F(WebFrameTest, ChromePageJavascript)
{
registerMockedChromeURLLoad("history.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
webViewHelper.webView()->layout();
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
EXPECT_NE(std::string::npos, content.find("Clobbered"));
}
TEST_F(WebFrameTest, ChromePageNoJavascript)
{
registerMockedChromeURLLoad("history.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);
WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs("chrome");
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
webViewHelper.webView()->layout();
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
EXPECT_EQ(std::string::npos, content.find("Clobbered"));
}
TEST_F(WebFrameTest, LocationSetHostWithMissingPort)
{
std::string fileName = "print-location-href.html";
registerMockedHttpURLLoad(fileName);
URLTestHelpers::registerMockedURLLoad(toKURL("http://www.test.com:0/" + fileName), WebString::fromUTF8(fileName));
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + fileName, true);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:location.host = 'www.test.com:'; void 0;");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
runPendingTasks();
webViewHelper.webView()->layout();
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
EXPECT_EQ("http://www.test.com:0/" + fileName, content);
}
TEST_F(WebFrameTest, LocationSetEmptyPort)
{
std::string fileName = "print-location-href.html";
registerMockedHttpURLLoad(fileName);
URLTestHelpers::registerMockedURLLoad(toKURL("http://www.test.com:0/" + fileName), WebString::fromUTF8(fileName));
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + fileName, true);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:location.port = ''; void 0;");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
runPendingTasks();
webViewHelper.webView()->layout();
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
EXPECT_EQ("http://www.test.com:0/" + fileName, content);
}
class CSSCallbackWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
CSSCallbackWebFrameClient() : m_updateCount(0) { }
virtual 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 WebData& html)
{
m_frame->loadHTMLString(html, toKURL("about:blank"));
runPendingTasks();
}
void executeScript(const WebString& code)
{
m_frame->executeScript(WebScriptSource(code));
m_frame->view()->layout();
runPendingTasks();
}
CSSCallbackWebFrameClient m_client;
FrameTestHelpers::WebViewHelper m_helper;
WebLocalFrame* m_frame;
};
TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet)
{
loadHTML(
"<style>"
"div.initial_on { -internal-callback: none; }"
"div.initial_off { -internal-callback: -internal-presence; }"
"</style>"
"<div class=\"initial_on\"></div>"
"<div class=\"initial_off\"></div>");
std::vector<WebString> selectors;
selectors.push_back(WebString::fromUTF8("div.initial_on"));
m_frame->document().watchCSSSelectors(WebVector<WebString>(selectors));
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_on"));
selectors.push_back(WebString::fromUTF8("div.initial_off"));
doc().watchCSSSelectors(WebVector<WebString>(selectors));
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(2, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("div.initial_off", "div.initial_on"));
doc().watchCSSSelectors(WebVector<WebString>());
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(3, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
}
TEST_F(WebFrameCSSCallbackTest, SharedRenderStyle)
{
std::vector<WebString> selectors;
selectors.push_back(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(), testing::ElementsAre("span"));
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(), testing::ElementsAre("span"));
executeScript(
"i1 = document.getElementById('first_span');"
"i1.parentNode.removeChild(i1);");
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"));
executeScript(
"i2 = document.getElementById('second_span');"
"i2.parentNode.removeChild(i2);");
EXPECT_EQ(2, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
}
TEST_F(WebFrameCSSCallbackTest, CatchesAttributeChange)
{
loadHTML("<span></span>");
std::vector<WebString> selectors;
selectors.push_back(WebString::fromUTF8("span[attr=\"value\"]"));
doc().watchCSSSelectors(WebVector<WebString>(selectors));
runPendingTasks();
EXPECT_EQ(0, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre());
executeScript(
"document.querySelector('span').setAttribute('attr', 'value');");
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span[attr=\"value\"]"));
}
TEST_F(WebFrameCSSCallbackTest, DisplayNone)
{
loadHTML("<div style='display:none'><span></span></div>");
std::vector<WebString> selectors;
selectors.push_back(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(), testing::ElementsAre("span"));
executeScript(
"d = document.querySelector('div');"
"d.style.display = 'none';");
EXPECT_EQ(2, updateCount()) << "Unmatch elements when they become undisplayed.";
EXPECT_THAT(matchedSelectors(), testing::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(), testing::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(), testing::ElementsAre());
}
TEST_F(WebFrameCSSCallbackTest, Reparenting)
{
loadHTML(
"<div id='d1'><span></span></div>"
"<div id='d2'></div>");
std::vector<WebString> selectors;
selectors.push_back(WebString::fromUTF8("span"));
doc().watchCSSSelectors(WebVector<WebString>(selectors));
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::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(), testing::ElementsAre("span"));
}
TEST_F(WebFrameCSSCallbackTest, MultiSelector)
{
loadHTML("<span></span>");
std::vector<WebString> selectors;
selectors.push_back(WebString::fromUTF8("span"));
selectors.push_back(WebString::fromUTF8("span,p"));
doc().watchCSSSelectors(WebVector<WebString>(selectors));
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span", "span, p"));
}
TEST_F(WebFrameCSSCallbackTest, InvalidSelector)
{
loadHTML("<p><span></span></p>");
std::vector<WebString> selectors;
selectors.push_back(WebString::fromUTF8("span"));
selectors.push_back(WebString::fromUTF8("["));
selectors.push_back(WebString::fromUTF8("p span"));
doc().watchCSSSelectors(WebVector<WebString>(selectors));
m_frame->view()->layout();
runPendingTasks();
EXPECT_EQ(1, updateCount());
EXPECT_THAT(matchedSelectors(), testing::ElementsAre("span"))
<< "An invalid selector shouldn't prevent other selectors from matching.";
}
TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck)
{
registerMockedHttpURLLoad("postmessage_test.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "postmessage_test.html", true);
WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)));
WebDOMEvent event = webViewHelper.webView()->mainFrame()->document().createEvent("MessageEvent");
WebDOMMessageEvent message = event.to<WebDOMMessageEvent>();
WebSerializedScriptValue data(WebSerializedScriptValue::fromString("foo"));
message.initMessageEvent("message", false, false, data, "http://origin.com", 0, "");
webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(correctOrigin, message);
WebSecurityOrigin incorrectOrigin(WebSecurityOrigin::create(toKURL(m_chromeURL)));
webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(incorrectOrigin, message);
webViewHelper.webView()->layout();
std::string content = webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
EXPECT_NE(std::string::npos, content.find("Message 1."));
EXPECT_EQ(std::string::npos, content.find("Message 2."));
}
TEST_F(WebFrameTest, PostMessageThenDetach)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank");
RefPtr<WebCore::LocalFrame> frame = webViewHelper.webViewImpl()->page()->mainFrame();
WebCore::NonThrowableExceptionState exceptionState;
frame->domWindow()->postMessage(WebCore::SerializedScriptValue::create("message"), 0, "*", frame->domWindow(), exceptionState);
webViewHelper.reset();
EXPECT_FALSE(exceptionState.hadException());
runPendingTasks();
}
class FixedLayoutTestWebViewClient : public WebViewClient {
public:
virtual WebScreenInfo screenInfo() OVERRIDE { return m_screenInfo; }
WebScreenInfo m_screenInfo;
};
static void enableViewportSettings(WebSettings* settings)
{
settings->setViewportMetaEnabled(true);
settings->setViewportEnabled(true);
settings->setMainFrameResizesAreOrientationChanges(true);
}
TEST_F(WebFrameTest, FrameViewNeedsLayoutOnFixedLayoutResize)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
webViewHelper.webViewImpl()->setFixedLayoutSize(WebCore::IntSize(100, 100));
EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->setFrameRect(WebCore::IntRect(0, 0, 641, 481));
EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
webViewHelper.webViewImpl()->layout();
}
static bool checkOrSetTextAutosizingMultiplier(Document* document, float multiplier, bool setMultiplier)
{
bool multiplierCheckedOrSetAtLeastOnce = false;
for (WebCore::RenderObject* renderer = document->renderer(); renderer; renderer = renderer->nextInPreOrder()) {
if (renderer->style()) {
if (setMultiplier)
renderer->style()->setTextAutosizingMultiplier(multiplier);
EXPECT_EQ(multiplier, renderer->style()->textAutosizingMultiplier());
multiplierCheckedOrSetAtLeastOnce = true;
}
}
return multiplierCheckedOrSetAtLeastOnce;
}
static bool setTextAutosizingMultiplier(Document* document, float multiplier)
{
return checkOrSetTextAutosizingMultiplier(document, multiplier, true);
}
static bool checkTextAutosizingMultiplier(Document* document, float multiplier)
{
return checkOrSetTextAutosizingMultiplier(document, multiplier, false);
}
TEST_F(WebFrameTest, ChangeInFixedLayoutResetsTextAutosizingMultipliers)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
WebCore::Document* document = webViewHelper.webViewImpl()->page()->mainFrame()->document();
document->settings()->setTextAutosizingEnabled(true);
EXPECT_TRUE(document->settings()->textAutosizingEnabled());
webViewHelper.webViewImpl()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webViewImpl()->layout();
EXPECT_TRUE(setTextAutosizingMultiplier(document, 2));
WebCore::ViewportDescription description = document->viewportDescription();
description.minWidth = WebCore::Length(100, WebCore::Fixed);
description.maxWidth = WebCore::Length(100, WebCore::Fixed);
webViewHelper.webViewImpl()->updatePageDefinedViewportConstraints(description);
EXPECT_TRUE(checkTextAutosizingMultiplier(document, 1));
}
TEST_F(WebFrameTest, SetFrameRectResetsTextAutosizingMultipliers)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("iframe_reload.html");
registerMockedHttpURLLoad("visible_iframe.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, 0, &client, enableViewportSettings);
WebCore::LocalFrame* mainFrame = webViewHelper.webViewImpl()->page()->mainFrame();
WebCore::Document* document = mainFrame->document();
WebCore::FrameView* frameView = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
document->settings()->setTextAutosizingEnabled(true);
EXPECT_TRUE(document->settings()->textAutosizingEnabled());
webViewHelper.webViewImpl()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webViewImpl()->layout();
for (WebCore::LocalFrame* frame = mainFrame; frame; frame = frame->tree().traverseNext())
EXPECT_TRUE(setTextAutosizingMultiplier(frame->document(), 2));
frameView->setFrameRect(WebCore::IntRect(0, 0, 200, 200));
for (WebCore::LocalFrame* frame = mainFrame; frame; frame = frame->tree().traverseNext())
EXPECT_TRUE(checkTextAutosizingMultiplier(frame->document(), 1));
}
TEST_F(WebFrameTest, FixedLayoutSizeStopsResizeFromChangingLayoutSize)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
int viewportWidth = 640;
int viewportHeight = 480;
int fixedLayoutWidth = viewportWidth / 2;
int fixedLayoutHeight = viewportHeight / 2;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
EXPECT_EQ(fixedLayoutWidth, webViewHelper.webViewImpl()->page()->mainFrame()->view()->layoutSize().width());
EXPECT_EQ(fixedLayoutHeight, webViewHelper.webViewImpl()->page()->mainFrame()->view()->layoutSize().height());
}
TEST_F(WebFrameTest, FixedLayoutSizePreventsResizeFromChangingPageScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
int viewportWidth = 640;
int viewportHeight = 480;
int fixedLayoutWidth = viewportWidth / 2;
int fixedLayoutHeight = viewportHeight / 2;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
float pageScaleFactor = webViewHelper.webView()->pageScaleFactor();
webViewHelper.webView()->resize(WebSize(viewportWidth * 2, viewportHeight * 2));
EXPECT_EQ(pageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, FixedLayoutSizePreventsLayoutFromChangingPageScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
int viewportWidth = 640;
int viewportHeight = 480;
int fixedLayoutWidth = viewportWidth * 2;
int fixedLayoutHeight = viewportHeight * 2;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, 0, enableViewportSettings);
webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
float pageScaleFactor = webViewHelper.webView()->pageScaleFactor();
webViewHelper.webView()->setFixedLayoutSize(WebSize(fixedLayoutWidth, fixedLayoutHeight));
webViewHelper.webView()->layout();
EXPECT_EQ(pageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, PreferredSizeAndContentSizeReportedCorrectlyWithZeroHeightFixedLayout)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("200-by-300.html");
int windowWidth = 100;
int windowHeight = 100;
int viewportWidth = 100;
int viewportHeight = 0;
int divWidth = 200;
int divHeight = 300;
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(windowWidth, windowHeight));
webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
EXPECT_EQ(divWidth, webViewHelper.webView()->mainFrame()->contentsSize().width);
EXPECT_EQ(divHeight, webViewHelper.webView()->mainFrame()->contentsSize().height);
EXPECT_EQ(divWidth, webViewHelper.webView()->contentsPreferredMinimumSize().width);
EXPECT_EQ(divHeight, webViewHelper.webView()->contentsPreferredMinimumSize().height);
}
TEST_F(WebFrameTest, DisablingFixedLayoutSizeSetsCorrectLayoutSize)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("no_viewport_tag.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
applyViewportStyleOverride(&webViewHelper);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setFixedLayoutSize(WebSize(viewportWidth, viewportHeight));
EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
webViewHelper.webView()->layout();
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
webViewHelper.webView()->setFixedLayoutSize(WebSize(0, 0));
EXPECT_TRUE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
webViewHelper.webView()->layout();
EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
}
TEST_F(WebFrameTest, ZeroHeightPositiveWidthNotIgnored)
{
UseMockScrollbarSettings mockScrollbarSettings;
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 1280;
int viewportHeight = 0;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
}
TEST_F(WebFrameTest, DeviceScaleFactorUsesDefaultWithoutViewportTag)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("no_viewport_tag.html");
int viewportWidth = 640;
int viewportHeight = 480;
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 2;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
EXPECT_EQ(2, webViewHelper.webView()->deviceScaleFactor());
webViewHelper.webView()->setPageScaleFactorLimits(1, 2);
webViewHelper.webView()->setPageScaleFactorPreservingScrollOffset(0.5);
webViewHelper.webView()->layout();
EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
webViewHelper.webView()->mainFrame()->contentAsText(1024).utf8();
}
TEST_F(WebFrameTest, FixedLayoutInitializeAtMinimumScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
int defaultFixedLayoutWidth = 980;
float minimumPageScaleFactor = viewportWidth / (float) defaultFixedLayoutWidth;
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
float userPinchPageScaleFactor = 2;
webViewHelper.webView()->setPageScaleFactorPreservingScrollOffset(userPinchPageScaleFactor);
webViewHelper.webView()->layout();
webViewHelper.webViewImpl()->didCommitLoad(false, false);
webViewHelper.webViewImpl()->didChangeContentsSize();
EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight + 100));
EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, WideDocumentInitializeAtMinimumScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("wide_document.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "wide_document.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
int wideDocumentWidth = 1500;
float minimumPageScaleFactor = viewportWidth / (float) wideDocumentWidth;
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
float userPinchPageScaleFactor = 2;
webViewHelper.webView()->setPageScaleFactorPreservingScrollOffset(userPinchPageScaleFactor);
webViewHelper.webView()->layout();
webViewHelper.webViewImpl()->didCommitLoad(false, false);
webViewHelper.webViewImpl()->didChangeContentsSize();
EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight + 100));
EXPECT_EQ(userPinchPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, DelayedViewportInitialScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(0.25f, webViewHelper.webView()->pageScaleFactor());
WebCore::Document* document = webViewHelper.webViewImpl()->page()->mainFrame()->document();
WebCore::ViewportDescription description = document->viewportDescription();
description.zoom = 2;
document->setViewportDescription(description);
webViewHelper.webView()->layout();
EXPECT_EQ(2, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, setLoadWithOverviewModeToFalse)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, SetLoadWithOverviewModeToFalseAndNoWideViewport)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("large-div.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, NoWideViewportIgnoresPageViewportWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
EXPECT_EQ(viewportHeight, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
}
TEST_F(WebFrameTest, NoWideViewportIgnoresPageViewportWidthButAccountsScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth / 2, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
EXPECT_EQ(viewportHeight / 2, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
}
TEST_F(WebFrameTest, WideViewportSetsTo980WithoutViewportTag)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("no_viewport_tag.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
applyViewportStyleOverride(&webViewHelper);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->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_F(WebFrameTest, NoWideViewportAndHeightInMeta)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-height-1000.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-height-1000.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
}
TEST_F(WebFrameTest, WideViewportSetsTo980WithAutoWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-2x-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
applyViewportStyleOverride(&webViewHelper);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->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_F(WebFrameTest, PageViewportInitialScaleOverridesLoadWithOverviewMode)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(2.0f, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, setInitialPageScaleFactorPermanently)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
float enforcedPageScaleFactor = 2.0f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
applyViewportStyleOverride(&webViewHelper);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->layout();
EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
int viewportWidth = 640;
int viewportHeight = 480;
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
webViewHelper.webView()->setInitialPageScaleOverride(-1);
webViewHelper.webView()->layout();
EXPECT_EQ(1.0, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, PermanentInitialPageScaleFactorOverridesLoadWithOverviewMode)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
float enforcedPageScaleFactor = 0.5f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-auto-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, PermanentInitialPageScaleFactorOverridesPageViewportInitialScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
float enforcedPageScaleFactor = 0.5f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-wide-2x-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, SmallPermanentInitialPageScaleFactorIsClobbered)
{
UseMockScrollbarSettings mockScrollbarSettings;
const char* pages[] = {
"viewport-device-0.5x-initial-scale.html",
"viewport-initial-scale-1.html",
"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 < ARRAY_SIZE(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 < ARRAY_SIZE(pages); ++i) {
for (int quirkEnabled = 0; quirkEnabled <= 1; ++quirkEnabled) {
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + pages[i], true, 0, &client, enableViewportSettings);
applyViewportStyleOverride(&webViewHelper);
webViewHelper.webView()->settings()->setClobberUserAgentInitialScaleQuirk(quirkEnabled);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
float expectedPageScaleFactor = quirkEnabled && i < ARRAY_SIZE(pageScaleFactors) ? pageScaleFactors[i] : enforcedPageScaleFactor;
EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
}
}
TEST_F(WebFrameTest, PermanentInitialPageScaleFactorAffectsLayoutWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
float enforcedPageScaleFactor = 0.5;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth / enforcedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
EXPECT_EQ(enforcedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, WideViewportInitialScaleDoesNotExpandFixedLayoutWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-device-0.5x-initial-scale.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-device-0.5x-initial-scale.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
webViewHelper.webView()->setFixedLayoutSize(WebSize(2000, 1500));
webViewHelper.webView()->layout();
EXPECT_EQ(2000, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
EXPECT_EQ(0.5f, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, WideViewportAndWideContentWithInitialScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("wide_document_width_viewport.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 600;
int viewportHeight = 800;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "wide_document_width_viewport.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
int wideDocumentWidth = 800;
float minimumPageScaleFactor = viewportWidth / (float) wideDocumentWidth;
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->minimumPageScaleFactor());
}
TEST_F(WebFrameTest, WideViewportQuirkClobbersHeight)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-height-1000.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 600;
int viewportHeight = 800;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-height-1000.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(800, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, LayoutSize320Quirk)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport/viewport-30.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 600;
int viewportHeight = 800;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport/viewport-30.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->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());
WebCore::Document* document = webViewHelper.webViewImpl()->page()->mainFrame()->document();
WebCore::ViewportDescription description = document->viewportDescription();
description.minWidth = WebCore::Length(321, WebCore::Fixed);
description.maxWidth = WebCore::Length(321, WebCore::Fixed);
document->setViewportDescription(description);
webViewHelper.webView()->layout();
EXPECT_EQ(321, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
description.minWidth = WebCore::Length(320, WebCore::Fixed);
description.maxWidth = WebCore::Length(320, WebCore::Fixed);
document->setViewportDescription(description);
webViewHelper.webView()->layout();
EXPECT_EQ(600, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
description = document->viewportDescription();
description.maxHeight = WebCore::Length(1000, WebCore::Fixed);
document->setViewportDescription(description);
webViewHelper.webView()->layout();
EXPECT_EQ(1000, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
description.maxHeight = WebCore::Length(320, WebCore::Fixed);
document->setViewportDescription(description);
webViewHelper.webView()->layout();
EXPECT_EQ(800, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
}
TEST_F(WebFrameTest, ZeroValuesQuirk)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-zero-values.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, &client, 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");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->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()->layout();
EXPECT_EQ(viewportWidth, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, OverflowHiddenDisablesScrolling)
{
registerMockedHttpURLLoad("body-overflow-hidden.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, &client);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
EXPECT_FALSE(view->userInputScrollable(WebCore::VerticalScrollbar));
}
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, 0, &client);
webViewHelper.webView()->settings()->setIgnoreMainFrameOverflowHiddenQuirk(true);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "body-overflow-hidden.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
EXPECT_TRUE(view->userInputScrollable(WebCore::VerticalScrollbar));
}
TEST_F(WebFrameTest, NonZeroValuesNoQuirk)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-nonzero-values.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
float expectedPageScaleFactor = 0.5f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "viewport-nonzero-values.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->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()->layout();
EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
EXPECT_EQ(expectedPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
}
TEST_F(WebFrameTest, setPageScaleFactorDoesNotLayout)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 64;
int viewportHeight = 48;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
webViewHelper.webViewImpl()->setPageScaleFactor(3, WebPoint());
EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
}
TEST_F(WebFrameTest, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
int prevLayoutCount = webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
webViewHelper.webViewImpl()->setPageScaleFactor(30, WebPoint());
EXPECT_FALSE(webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
EXPECT_EQ(prevLayoutCount, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
}
TEST_F(WebFrameTest, setPageScaleFactorBeforeFrameHasView)
{
registerMockedHttpURLLoad("fixed_layout.html");
float pageScaleFactor = 3;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:html", true, 0, 0);
webViewHelper.webView()->setPageScaleFactor(pageScaleFactor, WebPoint());
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "fixed_layout.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
EXPECT_EQ(pageScaleFactor, view->visibleContentScaleFactor());
}
TEST_F(WebFrameTest, pageScaleFactorWrittenToHistoryItem)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
webViewHelper.webView()->setPageScaleFactor(3, WebPoint());
EXPECT_EQ(3, webViewHelper.webViewImpl()->page()->mainFrame()->loader().currentItem()->pageScaleFactor());
}
TEST_F(WebFrameTest, initialScaleWrittenToHistoryItem)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
int defaultFixedLayoutWidth = 980;
float minimumPageScaleFactor = viewportWidth / (float) defaultFixedLayoutWidth;
EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webViewImpl()->page()->mainFrame()->loader().currentItem()->pageScaleFactor());
}
TEST_F(WebFrameTest, pageScaleFactorShrinksViewport)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("large-div.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 64;
int viewportHeight = 48;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
int viewportWidthMinusScrollbar = viewportWidth - (view->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
int viewportHeightMinusScrollbar = viewportHeight - (view->horizontalScrollbar()->isOverlayScrollbar() ? 0 : 15);
webViewHelper.webView()->setPageScaleFactor(2, WebPoint());
WebCore::IntSize unscaledSize = view->unscaledVisibleContentSize(WebCore::IncludeScrollbars);
EXPECT_EQ(viewportWidth, unscaledSize.width());
EXPECT_EQ(viewportHeight, unscaledSize.height());
WebCore::IntSize unscaledSizeMinusScrollbar = view->unscaledVisibleContentSize(WebCore::ExcludeScrollbars);
EXPECT_EQ(viewportWidthMinusScrollbar, unscaledSizeMinusScrollbar.width());
EXPECT_EQ(viewportHeightMinusScrollbar, unscaledSizeMinusScrollbar.height());
WebCore::IntSize scaledSize = view->visibleContentRect().size();
EXPECT_EQ(ceil(viewportWidthMinusScrollbar / 2.0), scaledSize.width());
EXPECT_EQ(ceil(viewportHeightMinusScrollbar / 2.0), scaledSize.height());
}
TEST_F(WebFrameTest, pageScaleFactorDoesNotApplyCssTransform)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
webViewHelper.webView()->setPageScaleFactor(2, WebPoint());
EXPECT_EQ(980, webViewHelper.webViewImpl()->page()->mainFrame()->contentRenderer()->unscaledDocumentRect().width());
EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
}
TEST_F(WebFrameTest, targetDensityDpiHigh)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-target-densitydpi-high.html");
FixedLayoutTestWebViewClient client;
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 < ARRAY_SIZE(deviceScaleFactors); ++i) {
float deviceScaleFactor = deviceScaleFactors[i];
float deviceDpi = deviceScaleFactor * 160.0f;
client.m_screenInfo.deviceScaleFactor = deviceScaleFactor;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-high.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
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_F(WebFrameTest, targetDensityDpiDevice)
{
UseMockScrollbarSettings mockScrollbarSettings;
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 < ARRAY_SIZE(deviceScaleFactors); ++i) {
client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->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_F(WebFrameTest, targetDensityDpiDeviceAndFixedWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
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 < ARRAY_SIZE(deviceScaleFactors); ++i) {
client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-target-densitydpi-device-and-fixed-width.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->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_F(WebFrameTest, NoWideViewportAndScaleLessThanOne)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-initial-scale-less-than-1.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1.33f;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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_F(WebFrameTest, NoWideViewportAndScaleLessThanOneWithDeviceWidth)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-initial-scale-less-than-1-device-width.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1.33f;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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_F(WebFrameTest, NoWideViewportAndNoViewportWithInitialPageScaleOverride)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("large-div.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
float enforcedPageScaleFactor = 5.0f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScale)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScaleForNonWideViewport)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1.33f;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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_F(WebFrameTest, NoUserScalableQuirkIgnoresViewportScaleForWideViewport)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("viewport-2x-initial-scale-non-user-scalable.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale-non-user-scalable.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(true);
webViewHelper.webView()->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_F(WebFrameTest, DesktopPageCanBeZoomedInWhenWideViewportIsTurnedOff)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("no_viewport_tag.html");
FixedLayoutTestWebViewClient client;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
webViewHelper.webView()->settings()->setUseWideViewport(false);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
EXPECT_NEAR(1.0f, webViewHelper.webView()->minimumPageScaleFactor(), 0.01f);
EXPECT_NEAR(5.0f, webViewHelper.webView()->maximumPageScaleFactor(), 0.01f);
}
class WebFrameResizeTest : public WebFrameTest {
protected:
static WebCore::FloatSize computeRelativeOffset(const WebCore::IntPoint& absoluteOffset, const WebCore::LayoutRect& rect)
{
WebCore::FloatSize relativeOffset = WebCore::FloatPoint(absoluteOffset) - 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) {
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad(url);
const float aspectRatio = static_cast<float>(viewportSize.width) / viewportSize.height;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + url, true, 0, 0, enableViewportSettings);
{
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
webViewHelper.webViewImpl()->setPageScaleFactor(initialPageScaleFactor, WebPoint());
ASSERT_EQ(viewportSize, webViewHelper.webViewImpl()->size());
ASSERT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
webViewHelper.webViewImpl()->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());
}
{
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
webViewHelper.webViewImpl()->setPageScaleFactor(initialPageScaleFactor, WebPoint(scrollOffset.width, scrollOffset.height));
webViewHelper.webViewImpl()->layout();
const WebSize expectedScrollOffset = webViewHelper.webViewImpl()->mainFrame()->scrollOffset();
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height * 0.8f));
EXPECT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
EXPECT_EQ(expectedScrollOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height * 0.8f));
EXPECT_EQ(initialPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor());
EXPECT_EQ(expectedScrollOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
}
{
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.height, viewportSize.width));
float pageScaleFactor = webViewHelper.webViewImpl()->pageScaleFactor();
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.width, viewportSize.height));
float expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? aspectRatio : 1);
EXPECT_NEAR(expectedPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor(), 0.05f);
webViewHelper.webViewImpl()->mainFrame()->setScrollOffset(scrollOffset);
WebCore::IntPoint anchorPoint = WebCore::IntPoint(scrollOffset) + WebCore::IntPoint(viewportSize.width / 2, 0);
RefPtr<WebCore::Node> anchorNode = webViewHelper.webViewImpl()->mainFrameImpl()->frame()->eventHandler().hitTestResultAtPoint(anchorPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent).innerNode();
ASSERT(anchorNode);
pageScaleFactor = webViewHelper.webViewImpl()->pageScaleFactor();
const WebCore::FloatSize preResizeRelativeOffset
= computeRelativeOffset(anchorPoint, anchorNode->boundingBox());
webViewHelper.webViewImpl()->resize(WebSize(viewportSize.height, viewportSize.width));
WebCore::IntPoint newAnchorPoint = WebCore::IntPoint(webViewHelper.webViewImpl()->mainFrame()->scrollOffset()) + WebCore::IntPoint(viewportSize.height / 2, 0);
const WebCore::FloatSize postResizeRelativeOffset
= computeRelativeOffset(newAnchorPoint, anchorNode->boundingBox());
EXPECT_NEAR(preResizeRelativeOffset.width(), postResizeRelativeOffset.width(), 0.15f);
expectedPageScaleFactor = pageScaleFactor * (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
EXPECT_NEAR(expectedPageScaleFactor, webViewHelper.webViewImpl()->pageScaleFactor(), 0.05f);
}
}
};
TEST_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForWidthEqualsDeviceWidth)
{
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_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedWidth)
{
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_F(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedLayout)
{
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_F(WebFrameTest, pageScaleFactorScalesPaintClip)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("large-div.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 50;
int viewportHeight = 50;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, 0, &client);
webViewHelper.webView()->settings()->setViewportEnabled(true);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
webViewHelper.webView()->setPageScaleFactor(0.5, WebPoint());
SkBitmap bitmap;
ASSERT_TRUE(bitmap.allocN32Pixels(200, 200));
bitmap.eraseColor(0);
SkCanvas canvas(bitmap);
WebCore::GraphicsContext context(&canvas);
context.setTrackOpaqueRegion(true);
EXPECT_EQ_RECT(WebCore::IntRect(0, 0, 0, 0), context.opaqueRegion().asRect());
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
WebCore::IntRect paintRect(0, 0, 200, 200);
view->paint(&context, paintRect);
int viewportWidthMinusScrollbar = 50 - (view->verticalScrollbar()->isOverlayScrollbar() ? 0 : 15);
int viewportHeightMinusScrollbar = 50 - (view->horizontalScrollbar()->isOverlayScrollbar() ? 0 : 15);
WebCore::IntRect clippedRect(0, 0, viewportWidthMinusScrollbar * 2, viewportHeightMinusScrollbar * 2);
EXPECT_EQ_RECT(clippedRect, context.opaqueRegion().asRect());
}
TEST_F(WebFrameTest, pageScaleFactorUpdatesScrollbars)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed_layout.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
EXPECT_EQ(view->scrollSize(WebCore::HorizontalScrollbar), view->contentsSize().width() - view->visibleContentRect().width());
EXPECT_EQ(view->scrollSize(WebCore::VerticalScrollbar), view->contentsSize().height() - view->visibleContentRect().height());
webViewHelper.webView()->setPageScaleFactor(10, WebPoint());
EXPECT_EQ(view->scrollSize(WebCore::HorizontalScrollbar), view->contentsSize().width() - view->visibleContentRect().width());
EXPECT_EQ(view->scrollSize(WebCore::VerticalScrollbar), view->contentsSize().height() - view->visibleContentRect().height());
}
TEST_F(WebFrameTest, CanOverrideScaleLimits)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("no_scale_for_you.html");
FixedLayoutTestWebViewClient client;
client.m_screenInfo.deviceScaleFactor = 1;
int viewportWidth = 640;
int viewportHeight = 480;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "no_scale_for_you.html", true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());
webViewHelper.webView()->setIgnoreViewportTagScaleLimits(true);
webViewHelper.webView()->layout();
EXPECT_EQ(1.0f, webViewHelper.webView()->minimumPageScaleFactor());
EXPECT_EQ(5.0f, webViewHelper.webView()->maximumPageScaleFactor());
webViewHelper.webView()->setIgnoreViewportTagScaleLimits(false);
webViewHelper.webView()->layout();
EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());
}
TEST_F(WebFrameTest, updateOverlayScrollbarLayers)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("large-div.html");
int viewWidth = 500;
int viewHeight = 500;
OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
webViewHelper.webView()->resize(WebSize(viewWidth, viewHeight));
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "large-div.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->layout();
WebCore::FrameView* view = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
EXPECT_TRUE(view->renderView()->compositor()->layerForHorizontalScrollbar());
EXPECT_TRUE(view->renderView()->compositor()->layerForVerticalScrollbar());
webViewHelper.webView()->resize(WebSize(viewWidth * 10, viewHeight * 10));
webViewHelper.webView()->layout();
EXPECT_FALSE(view->renderView()->compositor()->layerForHorizontalScrollbar());
EXPECT_FALSE(view->renderView()->compositor()->layerForVerticalScrollbar());
}
void setScaleAndScrollAndLayout(blink::WebView* webView, WebPoint scroll, float scale)
{
webView->setPageScaleFactor(scale, WebPoint(scroll.x, scroll.y));
webView->layout();
}
TEST_F(WebFrameTest, DivAutoZoomParamsTest)
{
registerMockedHttpURLLoad("get_scale_for_auto_zoom_into_div_test.html");
const float deviceScaleFactor = 2.0f;
int viewportWidth = 640 / deviceScaleFactor;
int viewportHeight = 1280 / deviceScaleFactor;
float doubleTapZoomAlreadyLegibleRatio = 1.2f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_auto_zoom_into_div_test.html");
webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
webViewHelper.webView()->setPageScaleFactorLimits(0.01f, 4);
webViewHelper.webView()->setPageScaleFactor(0.5f, WebPoint(0, 0));
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
WebRect wideDiv(200, 100, 400, 150);
WebRect tallDiv(200, 300, 400, 800);
WebRect doubleTapPointWide(wideDiv.x + 50, wideDiv.y + 50, touchPointPadding, touchPointPadding);
WebRect doubleTapPointTall(tallDiv.x + 50, tallDiv.y + 50, touchPointPadding, touchPointPadding);
WebRect wideBlockBounds;
WebRect tallBlockBounds;
float scale;
WebPoint scroll;
float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
wideBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointWide, false);
webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
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);
wideBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointWide, false);
webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
scale = webViewHelper.webViewImpl()->minimumPageScaleFactor();
setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), scale);
tallBlockBounds = webViewHelper.webViewImpl()->computeBlockBounds(doubleTapPointTall, false);
webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointTall.x, doubleTapPointTall.y), tallBlockBounds, touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
EXPECT_NEAR(viewportWidth / (float) tallDiv.width, scale, 0.1);
EXPECT_NEAR(tallDiv.x, scroll.x, 20);
EXPECT_NEAR(tallDiv.y, scroll.y, 20);
webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(250, 250), webViewHelper.webViewImpl()->computeBlockBounds(WebRect(250, 250, 10, 10), true), 0, doubleTapZoomAlreadyLegibleScale, scale, scroll);
EXPECT_NEAR(viewportWidth / (float) wideDiv.width, scale, 0.1);
}
void simulatePageScale(WebViewImpl* webViewImpl, float& scale)
{
WebCore::IntSize scrollDelta = webViewImpl->fakePageScaleAnimationTargetPositionForTesting() - webViewImpl->mainFrameImpl()->frameView()->scrollPosition();
float scaleDelta = webViewImpl->fakePageScaleAnimationPageScaleForTesting() / webViewImpl->pageScaleFactor();
webViewImpl->applyScrollAndScale(scrollDelta, scaleDelta);
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_F(WebFrameTest, DivAutoZoomWideDivTest)
{
registerMockedHttpURLLoad("get_wide_div_for_auto_zoom_test.html");
const float deviceScaleFactor = 2.0f;
int viewportWidth = 640 / deviceScaleFactor;
int viewportHeight = 1280 / deviceScaleFactor;
float doubleTapZoomAlreadyLegibleRatio = 1.2f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "get_wide_div_for_auto_zoom_test.html");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
webViewHelper.webView()->setPageScaleFactor(1.0f, WebPoint(0, 0));
webViewHelper.webView()->layout();
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_F(WebFrameTest, DivAutoZoomVeryTallTest)
{
registerMockedHttpURLLoad("very_tall_div.html");
const float deviceScaleFactor = 2.0f;
int viewportWidth = 640 / deviceScaleFactor;
int viewportHeight = 1280 / deviceScaleFactor;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "very_tall_div.html", true, 0, 0, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
webViewHelper.webView()->setPageScaleFactor(1.0f, WebPoint(0, 0));
webViewHelper.webView()->layout();
WebRect div(200, 300, 400, 5000);
WebPoint point(div.x + 50, div.y + 3000);
float scale;
WebPoint scroll;
WebRect blockBounds = webViewHelper.webViewImpl()->computeBlockBounds(WebRect(point.x, point.y, 0, 0), true);
webViewHelper.webViewImpl()->computeScaleAndScrollForBlockRect(point, blockBounds, 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");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
webViewHelper.webView()->setPageScaleFactor(0.5f, WebPoint(0, 0));
webViewHelper.webView()->layout();
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);
simulateDoubleTap(webViewHelper.webViewImpl(), topPoint, scale);
EXPECT_FLOAT_EQ(1, scale);
simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
simulateDoubleTap(webViewHelper.webViewImpl(), topPoint, scale);
EXPECT_FLOAT_EQ(1, scale);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 0.6f);
simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
EXPECT_FLOAT_EQ(1, scale);
simulateDoubleTap(webViewHelper.webViewImpl(), bottomPoint, scale);
EXPECT_FLOAT_EQ(webViewHelper.webViewImpl()->minimumPageScaleFactor(), scale);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
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");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setDeviceScaleFactor(1.5f);
webViewHelper.webView()->layout();
webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
WebRect div(200, 100, 200, 150);
WebPoint doubleTapPoint(div.x + 50, div.y + 50);
float scale;
webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
webViewHelper.webView()->layout();
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);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
webViewHelper.webView()->setPageScaleFactorLimits(1.1f, 4);
webViewHelper.webView()->layout();
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);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
webViewHelper.webView()->setPageScaleFactorLimits(0.95f, 4);
webViewHelper.webView()->layout();
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, 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");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
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;
float legibleScale = accessibilityFontScaleFactor;
setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), WebPoint(0, 0), (webViewHelper.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
float doubleTapZoomAlreadyLegibleScale = webViewHelper.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio;
webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
webViewHelper.webView()->layout();
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);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
webViewHelper.webView()->setPageScaleFactorLimits(1.0f, 4);
webViewHelper.webView()->layout();
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);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
webViewHelper.webView()->setPageScaleFactorLimits(0.95f, 4);
webViewHelper.webView()->layout();
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);
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.1f);
webViewHelper.webView()->setPageScaleFactorLimits(0.9f, 4);
webViewHelper.webView()->layout();
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, DivMultipleTargetZoomMultipleDivsTest)
{
registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
const float deviceScaleFactor = 2.0f;
int viewportWidth = 640 / deviceScaleFactor;
int viewportHeight = 1280 / deviceScaleFactor;
float doubleTapZoomAlreadyLegibleRatio = 1.2f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "get_multiple_divs_for_auto_zoom_test.html");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setPageScaleFactorLimits(0.5f, 4);
webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
webViewHelper.webView()->setPageScaleFactor(0.5f, WebPoint(0, 0));
webViewHelper.webView()->layout();
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(), WebPoint(0, 0));
simulateMultiTargetZoom(webViewHelper.webViewImpl(), topDiv, scale);
EXPECT_FLOAT_EQ(1, scale);
}
TEST_F(WebFrameTest, DivScrollIntoEditableTest)
{
registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");
int viewportWidth = 450;
int viewportHeight = 300;
float leftBoxRatio = 0.3f;
int caretPadding = 10;
float minReadableCaretHeight = 18.0f;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "get_scale_for_zoom_into_editable_test.html");
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->setPageScaleFactorLimits(1, 4);
webViewHelper.webView()->layout();
webViewHelper.webView()->setDeviceScaleFactor(1.5f);
webViewHelper.webView()->settings()->setAutoZoomFocusedNodeToLegibleScale(true);
webViewHelper.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
WebRect editBoxWithText(200, 200, 250, 20);
WebRect editBoxWithNoText(200, 250, 250, 20);
webViewHelper.webView()->advanceFocus(false);
webViewHelper.webView()->mainFrame()->document().getElementById("EditBoxWithText").to<WebInputElement>().setSelectionRange(1000, 1000);
setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
WebRect rect, caret;
webViewHelper.webViewImpl()->selectionBounds(caret, rect);
float scale;
WebCore::IntPoint scroll;
bool needAnimation;
webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
EXPECT_TRUE(needAnimation);
int hScroll = editBoxWithText.x - leftBoxRatio * viewportWidth / scale;
EXPECT_NEAR(hScroll, scroll.x(), 1);
int vScroll = editBoxWithText.y - (viewportHeight / scale - editBoxWithText.height) / 2;
EXPECT_NEAR(vScroll, scroll.y(), 1);
EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
viewportWidth = 200;
viewportHeight = 150;
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
webViewHelper.webViewImpl()->selectionBounds(caret, rect);
webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
EXPECT_TRUE(needAnimation);
hScroll = caret.x + caret.width + caretPadding - viewportWidth / scale;
EXPECT_NEAR(hScroll, scroll.x(), 1);
EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
webViewHelper.webView()->advanceFocus(false);
webViewHelper.webViewImpl()->selectionBounds(caret, rect);
webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
EXPECT_TRUE(needAnimation);
hScroll = editBoxWithNoText.x;
EXPECT_NEAR(hScroll, scroll.x(), 1);
vScroll = editBoxWithNoText.y - (viewportHeight / scale - editBoxWithNoText.height) / 2;
EXPECT_NEAR(vScroll, scroll.y(), 1);
EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);
setScaleAndScrollAndLayout(webViewHelper.webViewImpl(), scroll, scale);
webViewHelper.webView()->advanceFocus(true);
webViewHelper.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper.webViewImpl()->focusedElement(), scale, scroll, needAnimation);
EXPECT_FALSE(needAnimation);
}
class TestReloadDoesntRedirectWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
virtual WebNavigationPolicy decidePolicyForNavigation(
WebLocalFrame*, WebDataSource::ExtraData*, const WebURLRequest&, WebNavigationType,
WebNavigationPolicy defaultPolicy, bool isRedirect) OVERRIDE
{
EXPECT_FALSE(isRedirect);
return WebNavigationPolicyCurrentTab;
}
};
TEST_F(WebFrameTest, ReloadDoesntSetRedirect)
{
registerMockedHttpURLLoad("form.html");
TestReloadDoesntRedirectWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "form.html", false, &webFrameClient);
webViewHelper.webView()->mainFrame()->reload(true);
webViewHelper.webView()->mainFrame()->reload(true);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
}
TEST_F(WebFrameTest, ReloadWithOverrideURLPreservesState)
{
const std::string firstURL = "find.html";
const std::string secondURL = "form.html";
const std::string thirdURL = "history.html";
const float pageScaleFactor = 1.1684f;
const int pageWidth = 640;
const int pageHeight = 480;
registerMockedHttpURLLoad(firstURL);
registerMockedHttpURLLoad(secondURL);
registerMockedHttpURLLoad(thirdURL);
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + firstURL, true);
webViewHelper.webViewImpl()->resize(WebSize(pageWidth, pageHeight));
webViewHelper.webViewImpl()->mainFrame()->setScrollOffset(WebSize(pageWidth / 4, pageHeight / 4));
webViewHelper.webViewImpl()->setPageScaleFactorPreservingScrollOffset(pageScaleFactor);
WebSize previousOffset = webViewHelper.webViewImpl()->mainFrame()->scrollOffset();
float previousScale = webViewHelper.webViewImpl()->pageScaleFactor();
webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + secondURL), false);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
ASSERT_EQ(previousOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
ASSERT_EQ(previousScale, webViewHelper.webViewImpl()->pageScaleFactor());
webViewHelper.webViewImpl()->mainFrame()->reloadWithOverrideURL(toKURL(m_baseURL + thirdURL), true);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
ASSERT_EQ(previousOffset, webViewHelper.webViewImpl()->mainFrame()->scrollOffset());
ASSERT_EQ(previousScale, webViewHelper.webViewImpl()->pageScaleFactor());
}
TEST_F(WebFrameTest, ReloadWhileProvisional)
{
registerMockedHttpURLLoad("fixed_layout.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize();
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "fixed_layout.html");
webViewHelper.webView()->mainFrame()->reload(true);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
WebDataSource* dataSource = webViewHelper.webView()->mainFrame()->dataSource();
ASSERT_TRUE(dataSource);
EXPECT_EQ(toKURL(m_baseURL + "fixed_layout.html"), toKURL(dataSource->request().url().spec()));
}
TEST_F(WebFrameTest, AppendRedirects)
{
const std::string firstURL = "about:blank";
const std::string secondURL = "http://www.test.com";
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(firstURL, true);
WebDataSource* dataSource = webViewHelper.webView()->mainFrame()->dataSource();
ASSERT_TRUE(dataSource);
dataSource->appendRedirect(toKURL(secondURL));
WebVector<WebURL> redirects;
dataSource->redirectChain(redirects);
ASSERT_EQ(2U, redirects.size());
EXPECT_EQ(toKURL(firstURL), toKURL(redirects[0].spec().data()));
EXPECT_EQ(toKURL(secondURL), toKURL(redirects[1].spec().data()));
}
TEST_F(WebFrameTest, IframeRedirect)
{
registerMockedHttpURLLoad("iframe_redirect.html");
registerMockedHttpURLLoad("visible_iframe.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframe_redirect.html", true);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
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"), toKURL(redirects[0].spec().data()));
EXPECT_EQ(toKURL("http://www.test.com/visible_iframe.html"), toKURL(redirects[1].spec().data()));
}
TEST_F(WebFrameTest, ClearFocusedNodeTest)
{
registerMockedHttpURLLoad("iframe_clear_focused_node_test.html");
registerMockedHttpURLLoad("autofocus_input_field_iframe.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframe_clear_focused_node_test.html", true);
webViewHelper.webView()->clearFocusedElement();
EXPECT_EQ(0, webViewHelper.webViewImpl()->focusedElement());
}
class ContextLifetimeTestWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
struct Notification {
public:
Notification(WebLocalFrame* frame, v8::Handle<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;
};
virtual ~ContextLifetimeTestWebFrameClient()
{
reset();
}
void reset()
{
for (size_t i = 0; i < createNotifications.size(); ++i)
delete createNotifications[i];
for (size_t i = 0; i < releaseNotifications.size(); ++i)
delete releaseNotifications[i];
createNotifications.clear();
releaseNotifications.clear();
}
std::vector<Notification*> createNotifications;
std::vector<Notification*> releaseNotifications;
private:
virtual void didCreateScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int extensionGroup, int worldId) OVERRIDE
{
createNotifications.push_back(new Notification(frame, context, worldId));
}
virtual void willReleaseScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int worldId) OVERRIDE
{
releaseNotifications.push_back(new Notification(frame, context, worldId));
}
};
TEST_F(WebFrameTest, FLAKY_ContextNotificationsLoadUnload)
{
v8::HandleScope handleScope(v8::Isolate::GetCurrent());
registerMockedHttpURLLoad("context_notifications_test.html");
registerMockedHttpURLLoad("context_notifications_test_frame.html");
ContextLifetimeTestWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
WebFrame* childFrame = mainFrame->firstChild();
ASSERT_EQ(2u, webFrameClient.createNotifications.size());
EXPECT_EQ(0u, webFrameClient.releaseNotifications.size());
ContextLifetimeTestWebFrameClient::Notification* firstCreateNotification = webFrameClient.createNotifications[0];
ContextLifetimeTestWebFrameClient::Notification* 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);
webViewHelper.reset();
ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());
ContextLifetimeTestWebFrameClient::Notification* firstReleaseNotification = webFrameClient.releaseNotifications[0];
ContextLifetimeTestWebFrameClient::Notification* secondReleaseNotification = webFrameClient.releaseNotifications[1];
ASSERT_TRUE(firstCreateNotification->Equals(secondReleaseNotification));
ASSERT_TRUE(secondCreateNotification->Equals(firstReleaseNotification));
}
TEST_F(WebFrameTest, ContextNotificationsReload)
{
v8::HandleScope handleScope(v8::Isolate::GetCurrent());
registerMockedHttpURLLoad("context_notifications_test.html");
registerMockedHttpURLLoad("context_notifications_test_frame.html");
ContextLifetimeTestWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
webViewHelper.webView()->mainFrame()->reload(false);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
ASSERT_EQ(4u, webFrameClient.createNotifications.size());
ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());
for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
EXPECT_TRUE(webFrameClient.releaseNotifications[i]->Equals(
webFrameClient.createNotifications[webFrameClient.createNotifications.size() - 3 - i]));
}
WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
WebFrame* childFrame = mainFrame->firstChild();
ContextLifetimeTestWebFrameClient::Notification* firstRefreshNotification = webFrameClient.createNotifications[2];
ContextLifetimeTestWebFrameClient::Notification* 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_F(WebFrameTest, ContextNotificationsIsolatedWorlds)
{
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::HandleScope handleScope(isolate);
registerMockedHttpURLLoad("context_notifications_test.html");
registerMockedHttpURLLoad("context_notifications_test_frame.html");
ContextLifetimeTestWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html", true, &webFrameClient);
webFrameClient.reset();
int isolatedWorldId = 42;
WebScriptSource scriptSource("hi!");
int numSources = 1;
int extensionGroup = 0;
webViewHelper.webView()->mainFrame()->executeScriptInIsolatedWorld(isolatedWorldId, &scriptSource, numSources, extensionGroup);
ASSERT_EQ(1u, webFrameClient.createNotifications.size());
ContextLifetimeTestWebFrameClient::Notification* notification = webFrameClient.createNotifications[0];
ASSERT_EQ(isolatedWorldId, notification->worldId);
ASSERT_EQ(webViewHelper.webView()->mainFrame(), notification->frame);
ASSERT_NE(webViewHelper.webView()->mainFrame()->mainWorldScriptContext(), v8::Local<v8::Context>::New(isolate, notification->context));
webViewHelper.reset();
ASSERT_EQ(3u, webFrameClient.releaseNotifications.size());
int matchCount = 0;
for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
if (webFrameClient.releaseNotifications[i]->Equals(webFrameClient.createNotifications[0]))
++matchCount;
}
EXPECT_EQ(1, matchCount);
}
TEST_F(WebFrameTest, FindInPage)
{
registerMockedHttpURLLoad("find.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find.html");
WebFrame* frame = webViewHelper.webView()->mainFrame();
const int findIdentifier = 12345;
WebFindOptions options;
EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar1"), options, false, 0));
frame->stopFinding(false);
WebRange range = frame->selectionRange();
EXPECT_EQ(5, range.startOffset());
EXPECT_EQ(9, range.endOffset());
EXPECT_TRUE(frame->document().focusedElement().isNull());
EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar2"), options, false, 0));
frame->stopFinding(false);
range = frame->selectionRange();
ASSERT_FALSE(range.isNull());
EXPECT_EQ(5, range.startOffset());
EXPECT_EQ(9, range.endOffset());
EXPECT_EQ(WebString::fromUTF8("INPUT"), frame->document().focusedElement().tagName());
EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar3"), options, false, 0));
frame->stopFinding(false);
range = frame->selectionRange();
ASSERT_FALSE(range.isNull());
EXPECT_EQ(5, range.startOffset());
EXPECT_EQ(9, range.endOffset());
EXPECT_EQ(WebString::fromUTF8("TEXTAREA"), frame->document().focusedElement().tagName());
EXPECT_TRUE(frame->find(findIdentifier, WebString::fromUTF8("bar4"), options, false, 0));
frame->stopFinding(false);
range = frame->selectionRange();
ASSERT_FALSE(range.isNull());
EXPECT_EQ(0, range.startOffset());
EXPECT_EQ(4, range.endOffset());
EXPECT_EQ(WebString::fromUTF8("DIV"), frame->document().focusedElement().tagName());
EXPECT_FALSE(frame->find(findIdentifier, WebString::fromUTF8("bar5"), options, false, 0));
frame->stopFinding(false);
range = frame->selectionRange();
ASSERT_TRUE(range.isNull());
}
TEST_F(WebFrameTest, GetContentAsPlainText)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true);
webViewHelper.webView()->resize(WebSize(640, 480));
WebFrame* frame = webViewHelper.webView()->mainFrame();
const char simpleSource[] = "<div>Foo bar</div><div></div>baz";
WebCore::KURL testURL = toKURL("about:blank");
frame->loadHTMLString(simpleSource, testURL);
runPendingTasks();
const std::string expected("Foo bar\nbaz");
WebString text = frame->contentAsText(std::numeric_limits<size_t>::max());
EXPECT_EQ(expected, text.utf8());
const int length = 5;
text = frame->contentAsText(length);
EXPECT_EQ(expected.substr(0, length), text.utf8());
const char outerFrameSource[] = "Hello<iframe></iframe> world";
frame->loadHTMLString(outerFrameSource, testURL);
runPendingTasks();
WebFrame* subframe = frame->firstChild();
ASSERT_TRUE(subframe);
subframe->loadHTMLString("sub<p>text", testURL);
runPendingTasks();
text = frame->contentAsText(std::numeric_limits<size_t>::max());
EXPECT_EQ("Hello world\n\nsub\ntext", text.utf8());
text = frame->contentAsText(12);
EXPECT_EQ("Hello world", text.utf8());
}
TEST_F(WebFrameTest, GetFullHtmlOfPage)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
const char simpleSource[] = "<p>Hello</p><p>World</p>";
WebCore::KURL testURL = toKURL("about:blank");
frame->loadHTMLString(simpleSource, testURL);
runPendingTasks();
WebString text = frame->contentAsText(std::numeric_limits<size_t>::max());
EXPECT_EQ("Hello\n\nWorld", text.utf8());
const std::string html = frame->contentAsMarkup().utf8();
frame->loadHTMLString(WebData(html.c_str(), html.length()), testURL);
runPendingTasks();
EXPECT_EQ(html, frame->contentAsMarkup().utf8());
text = frame->contentAsText(std::numeric_limits<size_t>::max());
EXPECT_EQ("Hello\n\nWorld", text.utf8());
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:
virtual void didCreateScriptContext(WebLocalFrame* frame, v8::Handle<v8::Context> context, int extensionGroup, int worldId) OVERRIDE
{
frame->executeScript(WebScriptSource("window.history = 'replaced';"));
}
};
TEST_F(WebFrameTest, ExecuteScriptDuringDidCreateScriptContext)
{
registerMockedHttpURLLoad("hello_world.html");
TestExecuteScriptDuringDidCreateScriptContext webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true, &webFrameClient);
webViewHelper.webView()->mainFrame()->reload();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
}
class FindUpdateWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
FindUpdateWebFrameClient()
: m_findResultsAreReady(false)
, m_count(-1)
{
}
virtual void reportFindInPageMatchCount(int, int count, bool finalUpdate) OVERRIDE
{
m_count = count;
if (finalUpdate)
m_findResultsAreReady = true;
}
bool findResultsAreReady() const { return m_findResultsAreReady; }
int count() const { return m_count; }
private:
bool m_findResultsAreReady;
int m_count;
};
#if OS(MACOSX) || OS(ANDROID)
TEST_F(WebFrameTest, DISABLED_FindInPageMatchRects)
#else
TEST_F(WebFrameTest, FindInPageMatchRects)
#endif
{
registerMockedHttpURLLoad("find_in_page.html");
registerMockedHttpURLLoad("find_in_page_frame.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "result";
static const int kFindIdentifier = 12345;
static const int kNumResults = 19;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false, 0));
mainFrame->resetMatchCount();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
runPendingTasks();
EXPECT_TRUE(client.findResultsAreReady());
WebVector<WebFloatRect> webMatchRects;
mainFrame->findMatchRects(webMatchRects);
ASSERT_EQ(webMatchRects.size(), static_cast<size_t>(kNumResults));
int rectsVersion = mainFrame->findMatchMarkersVersion();
for (int resultIndex = 0; resultIndex < kNumResults; ++resultIndex) {
FloatRect resultRect = static_cast<FloatRect>(webMatchRects[resultIndex]);
EXPECT_EQ(mainFrame->selectNearestFindMatch(resultRect.center(), 0), resultIndex + 1);
Range* result = mainFrame->activeMatchFrame()->activeMatch();
ASSERT_TRUE(result);
result->setEnd(result->endContainer(), result->endOffset() + 3);
EXPECT_EQ(result->text(), String::format("%s %02d", kFindString, resultIndex));
FloatRect activeMatch = mainFrame->activeFindMatchRect();
EXPECT_EQ(enclosingIntRect(activeMatch), enclosingIntRect(resultRect));
EXPECT_EQ(mainFrame->findMatchMarkersVersion(), rectsVersion);
}
EXPECT_TRUE(webMatchRects[0].y < webMatchRects[1].y);
for (int resultIndex = 2; resultIndex < kNumResults; ++resultIndex) {
EXPECT_TRUE(webMatchRects[0].y < webMatchRects[resultIndex].y);
EXPECT_TRUE(webMatchRects[1].y > webMatchRects[resultIndex].y);
}
EXPECT_TRUE(webMatchRects[3].y > webMatchRects[2].y);
EXPECT_TRUE(webMatchRects[3].y > webMatchRects[4].y);
EXPECT_TRUE(webMatchRects[6].y < webMatchRects[7].y);
EXPECT_TRUE(webMatchRects[7].y < webMatchRects[8].y);
EXPECT_TRUE(webMatchRects[8].y < webMatchRects[9].y);
EXPECT_TRUE(webMatchRects[11].y > webMatchRects[10].y);
EXPECT_TRUE(webMatchRects[12].y > webMatchRects[10].y);
EXPECT_TRUE(webMatchRects[13].y > webMatchRects[10].y);
EXPECT_TRUE(webMatchRects[14].y > webMatchRects[10].y);
EXPECT_TRUE(webMatchRects[11].y < webMatchRects[15].y);
EXPECT_TRUE(webMatchRects[12].y < webMatchRects[15].y);
EXPECT_TRUE(webMatchRects[13].y < webMatchRects[15].y);
EXPECT_TRUE(webMatchRects[14].y < webMatchRects[15].y);
EXPECT_TRUE(webMatchRects[11].y < webMatchRects[12].y);
EXPECT_TRUE(webMatchRects[11].y < webMatchRects[13].y);
EXPECT_TRUE(webMatchRects[11].y < webMatchRects[14].y);
EXPECT_TRUE(webMatchRects[11].x > webMatchRects[12].x);
EXPECT_TRUE(webMatchRects[11].x > webMatchRects[13].x);
EXPECT_TRUE(webMatchRects[11].x > webMatchRects[14].x);
EXPECT_TRUE(webMatchRects[12].x < webMatchRects[11].x);
EXPECT_TRUE(webMatchRects[12].x < webMatchRects[13].x);
EXPECT_TRUE(webMatchRects[12].x < webMatchRects[14].x);
EXPECT_TRUE(webMatchRects[13].y < webMatchRects[12].y);
EXPECT_TRUE(webMatchRects[12].y < webMatchRects[14].y);
EXPECT_TRUE(webMatchRects[15].y > webMatchRects[14].y);
EXPECT_TRUE(webMatchRects[17].y > webMatchRects[18].y);
webViewHelper.webView()->resize(WebSize(800, 600));
runPendingTasks();
EXPECT_TRUE(mainFrame->findMatchMarkersVersion() != rectsVersion);
}
TEST_F(WebFrameTest, FindInPageSkipsHiddenFrames)
{
registerMockedHttpURLLoad("find_in_hidden_frame.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find_in_hidden_frame.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "hello";
static const int kFindIdentifier = 12345;
static const int kNumResults = 1;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false, 0));
mainFrame->resetMatchCount();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
runPendingTasks();
EXPECT_TRUE(client.findResultsAreReady());
EXPECT_EQ(kNumResults, client.count());
}
TEST_F(WebFrameTest, FindOnDetachedFrame)
{
registerMockedHttpURLLoad("find_in_page.html");
registerMockedHttpURLLoad("find_in_page_frame.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "result";
static const int kFindIdentifier = 12345;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
RefPtr<WebFrameImpl> secondFrame = toWebFrameImpl(mainFrame->traverseNext(false));
RefPtr<WebCore::LocalFrame> holdSecondFrame = secondFrame->frame();
EXPECT_TRUE(mainFrame->document().getElementById("frame").remove());
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->scopeStringMatches(kFindIdentifier, searchText, options, true);
runPendingTasks();
EXPECT_TRUE(client.findResultsAreReady());
holdSecondFrame.release();
}
TEST_F(WebFrameTest, FindDetachFrameBeforeScopeStrings)
{
registerMockedHttpURLLoad("find_in_page.html");
registerMockedHttpURLLoad("find_in_page_frame.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "result";
static const int kFindIdentifier = 12345;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebFrameImpl* secondFrame = toWebFrameImpl(mainFrame->traverseNext(false));
RefPtr<WebCore::LocalFrame> holdSecondFrame = secondFrame->frame();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
EXPECT_TRUE(frame->find(kFindIdentifier, searchText, options, false, 0));
runPendingTasks();
EXPECT_FALSE(client.findResultsAreReady());
EXPECT_TRUE(mainFrame->document().getElementById("frame").remove());
mainFrame->resetMatchCount();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
runPendingTasks();
EXPECT_TRUE(client.findResultsAreReady());
holdSecondFrame.release();
}
TEST_F(WebFrameTest, FindDetachFrameWhileScopingStrings)
{
registerMockedHttpURLLoad("find_in_page.html");
registerMockedHttpURLLoad("find_in_page_frame.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "result";
static const int kFindIdentifier = 12345;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebFrameImpl* secondFrame = toWebFrameImpl(mainFrame->traverseNext(false));
RefPtr<WebCore::LocalFrame> holdSecondFrame = secondFrame->frame();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
EXPECT_TRUE(frame->find(kFindIdentifier, searchText, options, false, 0));
runPendingTasks();
EXPECT_FALSE(client.findResultsAreReady());
mainFrame->resetMatchCount();
for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
frame->scopeStringMatches(kFindIdentifier, searchText, options, true);
EXPECT_TRUE(mainFrame->document().getElementById("frame").remove());
runPendingTasks();
EXPECT_TRUE(client.findResultsAreReady());
holdSecondFrame.release();
}
TEST_F(WebFrameTest, SetTickmarks)
{
registerMockedHttpURLLoad("find.html");
FindUpdateWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "find.html", true, &client);
webViewHelper.webView()->resize(WebSize(640, 480));
webViewHelper.webView()->layout();
runPendingTasks();
static const char* kFindString = "foo";
static const int kFindIdentifier = 12345;
WebFindOptions options;
WebString searchText = WebString::fromUTF8(kFindString);
WebFrameImpl* mainFrame = toWebFrameImpl(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());
WebCore::FrameView* frameView = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
RefPtr<WebCore::Scrollbar> scrollbar = frameView->createScrollbar(WebCore::HorizontalScrollbar);
Vector<WebCore::IntRect> originalTickmarks;
scrollbar->getTickmarks(originalTickmarks);
EXPECT_EQ(4u, originalTickmarks.size());
Vector<WebCore::IntRect> overridingTickmarksExpected;
overridingTickmarksExpected.append(WebCore::IntRect(0, 0, 100, 100));
overridingTickmarksExpected.append(WebCore::IntRect(0, 20, 100, 100));
overridingTickmarksExpected.append(WebCore::IntRect(0, 30, 100, 100));
mainFrame->setTickmarks(overridingTickmarksExpected);
Vector<WebCore::IntRect> overridingTickmarksActual;
scrollbar->getTickmarks(overridingTickmarksActual);
EXPECT_EQ(overridingTickmarksExpected, overridingTickmarksActual);
Vector<WebCore::IntRect> resetTickmarks;
mainFrame->setTickmarks(resetTickmarks);
Vector<WebCore::IntRect> originalTickmarksAfterReset;
scrollbar->getTickmarks(originalTickmarksAfterReset);
EXPECT_EQ(originalTickmarks, originalTickmarksAfterReset);
}
static WebPoint topLeft(const WebRect& rect)
{
return WebPoint(rect.x, rect.y);
}
static WebPoint bottomRightMinusOne(const WebRect& rect)
{
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).boundsInViewportSpace();
}
static std::string selectionAsString(WebFrame* frame)
{
return frame->selectionAsText().utf8();
}
TEST_F(WebFrameTest, SelectRange)
{
WebFrame* frame;
WebRect startWebRect;
WebRect endWebRect;
registerMockedHttpURLLoad("select_range_basic.html");
registerMockedHttpURLLoad("select_range_scroll.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "select_range_basic.html", &webViewHelper);
frame = webViewHelper.webView()->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));
EXPECT_EQ("Some test text for testing.", selectionAsString(frame));
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));
EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame));
}
TEST_F(WebFrameTest, SelectRangeInIframe)
{
WebFrame* frame;
WebRect startWebRect;
WebRect endWebRect;
registerMockedHttpURLLoad("select_range_iframe.html");
registerMockedHttpURLLoad("select_range_basic.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "select_range_iframe.html", &webViewHelper);
frame = webViewHelper.webView()->mainFrame();
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));
EXPECT_EQ("Some test text for testing.", selectionAsString(subframe));
}
TEST_F(WebFrameTest, SelectRangeDivContentEditable)
{
WebFrame* frame;
WebRect startWebRect;
WebRect endWebRect;
registerMockedHttpURLLoad("select_range_div_editable.html");
FrameTestHelpers::WebViewHelper webViewHelper;
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));
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));
}
TEST_F(WebFrameTest, DISABLED_SelectRangeSpanContentEditable)
{
WebFrame* frame;
WebRect startWebRect;
WebRect endWebRect;
registerMockedHttpURLLoad("select_range_span_editable.html");
FrameTestHelpers::WebViewHelper webViewHelper;
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));
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_F(WebFrameTest, SelectRangeCanMoveSelectionStart)
{
registerMockedHttpURLLoad("text_selection.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "text_selection.html", &webViewHelper);
WebFrame* frame = webViewHelper.webView()->mainFrame();
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));
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));
EXPECT_FALSE(frame->selectionRange().isNull());
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));
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));
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));
frame->executeScript(WebScriptSource("selectElement('editable_2');"));
EXPECT_EQ("Editable 2.", selectionAsString(frame));
frame->selectRange(bottomRightMinusOne(elementBounds(frame, "editable_2")), topLeft(elementBounds(frame, "header_2")));
}
TEST_F(WebFrameTest, SelectRangeCanMoveSelectionEnd)
{
registerMockedHttpURLLoad("text_selection.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "text_selection.html", &webViewHelper);
WebFrame* frame = webViewHelper.webView()->mainFrame();
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));
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));
EXPECT_FALSE(frame->selectionRange().isNull());
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));
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));
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));
frame->executeScript(WebScriptSource("selectElement('editable_1');"));
EXPECT_EQ("Editable 1.", selectionAsString(frame));
frame->selectRange(topLeft(elementBounds(frame, "editable_1")), bottomRightMinusOne(elementBounds(frame, "footer_1")));
}
static int computeOffset(WebCore::RenderObject* renderer, int x, int y)
{
return WebCore::VisiblePosition(renderer->positionForPoint(WebCore::LayoutPoint(x, y))).deepEquivalent().computeOffsetInContainerNode();
}
TEST_F(WebFrameTest, DISABLED_PositionForPointTest)
{
registerMockedHttpURLLoad("select_range_span_editable.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html", &webViewHelper);
WebFrameImpl* mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebCore::RenderObject* renderer = mainFrame->frame()->selection().rootEditableElement()->renderer();
EXPECT_EQ(0, computeOffset(renderer, -1, -1));
EXPECT_EQ(64, computeOffset(renderer, 1000, 1000));
registerMockedHttpURLLoad("select_range_div_editable.html");
initializeTextSelectionWebView(m_baseURL + "select_range_div_editable.html", &webViewHelper);
mainFrame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
renderer = mainFrame->frame()->selection().rootEditableElement()->renderer();
EXPECT_EQ(0, computeOffset(renderer, -1, -1));
EXPECT_EQ(64, computeOffset(renderer, 1000, 1000));
}
#if !OS(MACOSX)
TEST_F(WebFrameTest, SelectRangeStaysHorizontallyAlignedWhenMoved)
{
registerMockedHttpURLLoad("move_caret.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "move_caret.html", &webViewHelper);
WebFrameImpl* frame = toWebFrameImpl(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_F(WebFrameTest, MoveCaretStaysHorizontallyAlignedWhenMoved)
{
WebFrameImpl* frame;
registerMockedHttpURLLoad("move_caret.html");
FrameTestHelpers::WebViewHelper webViewHelper;
initializeTextSelectionWebView(m_baseURL + "move_caret.html", &webViewHelper);
frame = (WebFrameImpl*)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 DisambiguationPopupTestWebViewClient : public WebViewClient {
public:
virtual bool didTapMultipleTargets(const WebGestureEvent&, 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.x = x;
event.y = y;
event.data.tap.width = 50;
event.data.tap.height = 50;
return event;
}
TEST_F(WebFrameTest, DisambiguationPopup)
{
const std::string htmlFile = "disambiguation_popup.html";
registerMockedHttpURLLoad(htmlFile);
DisambiguationPopupTestWebViewClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
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());
}
}
TEST_F(WebFrameTest, DisambiguationPopupNoContainer)
{
registerMockedHttpURLLoad("disambiguation_popup_no_container.html");
DisambiguationPopupTestWebViewClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "disambiguation_popup_no_container.html", true, 0, &client);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
client.resetTriggered();
webViewHelper.webView()->handleInputEvent(fatTap(50, 50));
EXPECT_FALSE(client.triggered());
}
TEST_F(WebFrameTest, DisambiguationPopupMobileSite)
{
UseMockScrollbarSettings mockScrollbarSettings;
const std::string htmlFile = "disambiguation_popup_mobile_site.html";
registerMockedHttpURLLoad(htmlFile);
DisambiguationPopupTestWebViewClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
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, DisambiguationPopupViewportSite)
{
UseMockScrollbarSettings mockScrollbarSettings;
const std::string htmlFile = "disambiguation_popup_viewport_site.html";
registerMockedHttpURLLoad(htmlFile);
DisambiguationPopupTestWebViewClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client, enableViewportSettings);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
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, 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;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client);
webViewHelper.webView()->resize(WebSize(viewportWidth, viewportHeight));
webViewHelper.webView()->layout();
client.resetTriggered();
webViewHelper.webView()->handleInputEvent(fatTap(viewportWidth / 2, 0));
EXPECT_FALSE(client.triggered());
client.resetTriggered();
webViewHelper.webView()->handleInputEvent(fatTap(viewportWidth / 2, divHeight));
EXPECT_TRUE(client.triggered());
client.resetTriggered();
webViewHelper.webView()->handleInputEvent(fatTap(viewportWidth / 2, divHeight * 3.25));
EXPECT_FALSE(client.triggered());
}
TEST_F(WebFrameTest, DisambiguationPopupPageScale)
{
registerMockedHttpURLLoad("disambiguation_popup_page_scale.html");
DisambiguationPopupTestWebViewClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "disambiguation_popup_page_scale.html", true, 0, &client);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
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, WebPoint(0, 0));
webViewHelper.webView()->layout();
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)
{
frame->loadHTMLString("This should appear", toKURL("data:text/html,chromewebdata"), error.unreachableURL, true);
runPendingTasks();
}
virtual void didCommitProvisionalLoad(WebLocalFrame* frame, bool)
{
if (frame->dataSource()->response().url() != WebURL(URLTestHelpers::toKURL("about:blank")))
m_commitCalled = true;
}
bool commitCalled() const { return m_commitCalled; }
private:
bool m_commitCalled;
};
TEST_F(WebFrameTest, ReplaceNavigationAfterHistoryNavigation)
{
TestSubstituteDataWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true, &webFrameClient);
runPendingTasks();
WebFrame* frame = webViewHelper.webView()->mainFrame();
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()->unitTestSupport()->registerMockedErrorURL(URLTestHelpers::toKURL(errorURL), response, error);
frame->loadHistoryItem(errorHistoryItem);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
WebString text = frame->contentAsText(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)
{
}
virtual void didCommitProvisionalLoad(WebLocalFrame*, bool) OVERRIDE
{
m_numBodies = 0;
m_didLoad = true;
}
virtual void didCreateDocumentElement(WebLocalFrame*) OVERRIDE
{
EXPECT_EQ(0, m_numBodies);
}
virtual void willInsertBody(WebLocalFrame*) OVERRIDE
{
m_numBodies++;
}
int m_numBodies;
bool m_didLoad;
};
TEST_F(WebFrameTest, HTMLDocument)
{
registerMockedHttpURLLoad("clipped-body.html");
TestWillInsertBodyWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "clipped-body.html", false, &webFrameClient);
EXPECT_TRUE(webFrameClient.m_didLoad);
EXPECT_EQ(1, webFrameClient.m_numBodies);
}
TEST_F(WebFrameTest, EmptyDocument)
{
registerMockedHttpURLLoad("pageserializer/green_rectangle.svg");
TestWillInsertBodyWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(false, &webFrameClient);
EXPECT_FALSE(webFrameClient.m_didLoad);
EXPECT_EQ(1, webFrameClient.m_numBodies);
}
TEST_F(WebFrameTest, MoveCaretSelectionTowardsWindowPointWithNoSelection)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
frame->moveCaretSelection(WebPoint(0, 0));
}
class SpellCheckClient : public WebSpellCheckClient {
public:
explicit SpellCheckClient(uint32_t hash = 0) : m_numberOfTimesChecked(0), m_hash(hash) { }
virtual ~SpellCheckClient() { }
virtual void requestCheckingOfText(const blink::WebString&, const blink::WebVector<uint32_t>&, const blink::WebVector<unsigned>&, blink::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_F(WebFrameTest, ReplaceMisspelledRange)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
SpellCheckClient spellcheck;
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "_wellcome_.");
const int allTextBeginOffset = 0;
const int allTextLength = 11;
frame->selectRange(WebRange::fromDocumentRange(frame, allTextBeginOffset, allTextLength));
RefPtrWillBeRawPtr<Range> selectionRange = frame->frame()->selection().toNormalizedRange();
EXPECT_EQ(1, spellcheck.numberOfTimesChecked());
EXPECT_EQ(1U, document->markers().markersInRange(selectionRange.get(), DocumentMarker::Spelling).size());
frame->replaceMisspelledRange("welcome");
EXPECT_EQ("_welcome_.", frame->contentAsText(std::numeric_limits<size_t>::max()).utf8());
}
TEST_F(WebFrameTest, RemoveSpellingMarkers)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
SpellCheckClient spellcheck;
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "_wellcome_.");
frame->removeSpellingMarkers();
const int allTextBeginOffset = 0;
const int allTextLength = 11;
frame->selectRange(WebRange::fromDocumentRange(frame, allTextBeginOffset, allTextLength));
RefPtrWillBeRawPtr<Range> selectionRange = frame->frame()->selection().toNormalizedRange();
EXPECT_EQ(0U, document->markers().markersInRange(selectionRange.get(), DocumentMarker::Spelling).size());
}
TEST_F(WebFrameTest, MarkerHashIdentifiers) {
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
static const uint32_t kHash = 42;
SpellCheckClient spellcheck(kHash);
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "wellcome.");
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 blink::WebString&,
const blink::WebVector<uint32_t>&,
const blink::WebVector<unsigned>&,
blink::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;
}
blink::WebTextCheckingCompletion* m_completion;
};
TEST_F(WebFrameTest, SlowSpellcheckMarkerPosition)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
StubbornSpellCheckClient spellcheck;
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebInputElement webInputElement = frame->document().getElementById("data").to<WebInputElement>();
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "wellcome ");
webInputElement.setSelectionRange(0, 0);
document->execCommand("InsertText", false, "he");
spellcheck.kick();
WebVector<uint32_t> documentMarkers;
webViewHelper.webView()->spellingMarkers(&documentMarkers);
EXPECT_EQ(0U, documentMarkers.size());
}
TEST_F(WebFrameTest, CancelSpellingRequestCrash)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
webViewHelper.webView()->setSpellCheckClient(0);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
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_F(WebFrameTest, SpellcheckResultErasesMarkers)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
StubbornSpellCheckClient spellcheck;
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebInputElement webInputElement = frame->document().getElementById("data").to<WebInputElement>();
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "welcome ");
document->markers().addMarker(rangeOfContents(element->toNode()).get(), DocumentMarker::Spelling);
document->markers().addMarker(rangeOfContents(element->toNode()).get(), DocumentMarker::Grammar);
document->markers().addMarker(rangeOfContents(element->toNode()).get(), DocumentMarker::InvisibleSpellcheck);
EXPECT_EQ(3U, document->markers().markers().size());
spellcheck.kickNoResults();
EXPECT_EQ(0U, document->markers().markers().size());
}
TEST_F(WebFrameTest, SpellcheckResultsSavedInDocument)
{
registerMockedHttpURLLoad("spell.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
StubbornSpellCheckClient spellcheck;
webViewHelper.webView()->setSpellCheckClient(&spellcheck);
WebFrameImpl* frame = toWebFrameImpl(webViewHelper.webView()->mainFrame());
WebInputElement webInputElement = frame->document().getElementById("data").to<WebInputElement>();
Document* document = frame->frame()->document();
Element* element = document->getElementById("data");
webViewHelper.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
webViewHelper.webView()->settings()->setUnifiedTextCheckerEnabled(true);
webViewHelper.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin);
element->focus();
document->execCommand("InsertText", false, "wellcome ");
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 ");
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 ");
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(WebLocalFrame* frame)
{
EXPECT_TRUE(!m_didAccessInitialDocument);
m_didAccessInitialDocument = true;
}
bool m_didAccessInitialDocument;
};
TEST_F(WebFrameTest, DidAccessInitialDocumentBody)
{
TestAccessInitialDocumentWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, &webFrameClient);
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
FrameTestHelpers::WebViewHelper newWebViewHelper;
WebView* newView = newWebViewHelper.initialize(true);
newView->mainFrame()->setOpener(webViewHelper.webView()->mainFrame());
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}
TEST_F(WebFrameTest, DidAccessInitialDocumentNavigator)
{
TestAccessInitialDocumentWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, &webFrameClient);
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
FrameTestHelpers::WebViewHelper newWebViewHelper;
WebView* newView = newWebViewHelper.initialize(true);
newView->mainFrame()->setOpener(webViewHelper.webView()->mainFrame());
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("console.log(window.opener.navigator);"));
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}
TEST_F(WebFrameTest, DidAccessInitialDocumentViaJavascriptUrl)
{
TestAccessInitialDocumentWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, &webFrameClient);
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Modified'))");
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}
#if OS(WIN)
TEST_F(WebFrameTest, DISABLED_DidAccessInitialDocumentBodyBeforeModalDialog)
#else
TEST_F(WebFrameTest, DidAccessInitialDocumentBodyBeforeModalDialog)
#endif
{
TestAccessInitialDocumentWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, &webFrameClient);
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
FrameTestHelpers::WebViewHelper newWebViewHelper;
WebView* newView = newWebViewHelper.initialize(true);
newView->mainFrame()->setOpener(webViewHelper.webView()->mainFrame());
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.confirm('Modal');"));
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}
#if OS(WIN)
TEST_F(WebFrameTest, DISABLED_DidWriteToInitialDocumentBeforeModalDialog)
#else
TEST_F(WebFrameTest, DidWriteToInitialDocumentBeforeModalDialog)
#endif
{
TestAccessInitialDocumentWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, &webFrameClient);
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
FrameTestHelpers::WebViewHelper newWebViewHelper;
WebView* newView = newWebViewHelper.initialize(true);
newView->mainFrame()->setOpener(webViewHelper.webView()->mainFrame());
runPendingTasks();
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.document.write('Modified');"));
EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);
newView->mainFrame()->executeScript(
WebScriptSource("window.opener.confirm('Modal');"));
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
runPendingTasks();
EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}
class TestMainFrameUserOrProgrammaticScrollFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
TestMainFrameUserOrProgrammaticScrollFrameClient() { reset(); }
void reset()
{
m_didScrollMainFrame = false;
m_wasProgrammaticScroll = false;
}
bool wasUserScroll() const { return m_didScrollMainFrame && !m_wasProgrammaticScroll; }
bool wasProgrammaticScroll() const { return m_didScrollMainFrame && m_wasProgrammaticScroll; }
virtual void didChangeScrollOffset(WebLocalFrame* frame) OVERRIDE
{
if (frame->parent())
return;
EXPECT_FALSE(m_didScrollMainFrame);
WebCore::FrameView* view = toWebFrameImpl(frame)->frameView();
if (view) {
m_didScrollMainFrame = true;
m_wasProgrammaticScroll = view->inProgrammaticScroll();
}
}
private:
bool m_didScrollMainFrame;
bool m_wasProgrammaticScroll;
};
TEST_F(WebFrameTest, CompositorScrollIsUserScrollLongPage)
{
registerMockedHttpURLLoad("long_scroll.html");
TestMainFrameUserOrProgrammaticScrollFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "long_scroll.html", true, &client);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
EXPECT_FALSE(client.wasUserScroll());
EXPECT_FALSE(client.wasProgrammaticScroll());
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(0, 1), 1.1f);
EXPECT_TRUE(client.wasUserScroll());
client.reset();
EXPECT_FALSE(client.wasUserScroll());
EXPECT_FALSE(client.wasProgrammaticScroll());
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(0, 1), 1.0f);
EXPECT_TRUE(client.wasUserScroll());
client.reset();
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(), 1.0f);
EXPECT_FALSE(client.wasUserScroll());
EXPECT_FALSE(client.wasProgrammaticScroll());
client.reset();
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(9, 13), 0.6f);
EXPECT_TRUE(client.wasUserScroll());
client.reset();
WebFrameImpl* frameImpl = webViewHelper.webViewImpl()->mainFrameImpl();
frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
EXPECT_FALSE(client.wasUserScroll());
EXPECT_TRUE(client.wasProgrammaticScroll());
client.reset();
frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
EXPECT_FALSE(client.wasProgrammaticScroll());
EXPECT_FALSE(client.wasUserScroll());
client.reset();
}
TEST_F(WebFrameTest, CompositorScrollIsUserScrollShortPage)
{
registerMockedHttpURLLoad("short_scroll.html");
TestMainFrameUserOrProgrammaticScrollFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "short_scroll.html", true, &client);
webViewHelper.webView()->resize(WebSize(1000, 1000));
webViewHelper.webView()->layout();
EXPECT_FALSE(client.wasUserScroll());
EXPECT_FALSE(client.wasProgrammaticScroll());
webViewHelper.webViewImpl()->applyScrollAndScale(WebSize(9, 13), 2.0f);
EXPECT_FALSE(client.wasProgrammaticScroll());
EXPECT_TRUE(client.wasUserScroll());
client.reset();
}
TEST_F(WebFrameTest, FirstPartyForCookiesForRedirect)
{
WTF::String filePath = Platform::current()->unitTestSupport()->webKitRootDir();
filePath.append("/Source/web/tests/data/first_party.html");
WebURL testURL(toKURL("http://www.test.com/first_party_redirect.html"));
char redirect[] = "http://www.test.com/first_party.html";
WebURL redirectURL(toKURL(redirect));
WebURLResponse redirectResponse;
redirectResponse.initialize();
redirectResponse.setMIMEType("text/html");
redirectResponse.setHTTPStatusCode(302);
redirectResponse.setHTTPHeaderField("Location", redirect);
Platform::current()->unitTestSupport()->registerMockedURL(testURL, redirectResponse, filePath);
WebURLResponse finalResponse;
finalResponse.initialize();
finalResponse.setMIMEType("text/html");
Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, finalResponse, filePath);
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "first_party_redirect.html", true);
EXPECT_TRUE(webViewHelper.webView()->mainFrame()->document().firstPartyForCookies() == redirectURL);
}
class TestNavigationPolicyWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
virtual void didNavigateWithinPage(WebLocalFrame*, bool)
{
EXPECT_TRUE(false);
}
};
TEST_F(WebFrameTest, SimulateFragmentAnchorMiddleClick)
{
registerMockedHttpURLLoad("fragment_middle_click.html");
TestNavigationPolicyWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true, &client);
WebCore::Document* document = webViewHelper.webViewImpl()->page()->mainFrame()->document();
WebCore::KURL destination = document->url();
destination.setFragmentIdentifier("test");
RefPtrWillBeRawPtr<WebCore::Event> event = WebCore::MouseEvent::create(WebCore::EventTypeNames::click, false, false,
document->domWindow(), 0, 0, 0, 0, 0, 0, 0, false, false, false, false, 1, nullptr, nullptr);
WebCore::FrameLoadRequest frameRequest(document, WebCore::ResourceRequest(destination));
frameRequest.setTriggeringEvent(event);
webViewHelper.webViewImpl()->page()->mainFrame()->loader().load(frameRequest);
}
class TestNewWindowWebViewClient : public WebViewClient {
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)
{
}
virtual WebNavigationPolicy decidePolicyForNavigation(WebLocalFrame*, WebDataSource::ExtraData*, const WebURLRequest&,
WebNavigationType, WebNavigationPolicy policy, bool) OVERRIDE
{
m_decidePolicyCallCount++;
return policy;
}
int decidePolicyCallCount() const { return m_decidePolicyCallCount; }
private:
int m_decidePolicyCallCount;
};
TEST_F(WebFrameTest, ModifiedClickNewWindow)
{
registerMockedHttpURLLoad("ctrl_click.html");
registerMockedHttpURLLoad("hello_world.html");
TestNewWindowWebViewClient webViewClient;
TestNewWindowWebFrameClient webFrameClient;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "ctrl_click.html", true, &webFrameClient, &webViewClient);
WebCore::Document* document = webViewHelper.webViewImpl()->page()->mainFrame()->document();
WebCore::KURL destination = toKURL(m_baseURL + "hello_world.html");
RefPtrWillBeRawPtr<WebCore::Event> event = WebCore::MouseEvent::create(WebCore::EventTypeNames::click, false, false,
document->domWindow(), 0, 0, 0, 0, 0, 0, 0, true, false, false, false, 0, nullptr, nullptr);
WebCore::FrameLoadRequest frameRequest(document, WebCore::ResourceRequest(destination));
frameRequest.setTriggeringEvent(event);
WebCore::UserGestureIndicator gesture(WebCore::DefinitelyProcessingUserGesture);
webViewHelper.webViewImpl()->page()->mainFrame()->loader().load(frameRequest);
EXPECT_EQ(2, webFrameClient.decidePolicyCallCount());
}
TEST_F(WebFrameTest, BackToReload)
{
registerMockedHttpURLLoad("fragment_middle_click.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
WebHistoryItem firstItem = frame->currentHistoryItem();
EXPECT_FALSE(firstItem.isNull());
registerMockedHttpURLLoad("white-1x1.png");
FrameTestHelpers::loadFrame(frame, m_baseURL + "white-1x1.png");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_FALSE(frame->previousHistoryItem().isNull());
EXPECT_EQ(firstItem.urlString(), frame->previousHistoryItem().urlString());
frame->loadHistoryItem(frame->previousHistoryItem());
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(firstItem.urlString(), frame->currentHistoryItem().urlString());
frame->reload();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData, frame->dataSource()->request().cachePolicy());
}
TEST_F(WebFrameTest, BackDuringChildFrameReload)
{
registerMockedHttpURLLoad("page_with_blank_iframe.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "page_with_blank_iframe.html", true);
WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
WebFrame* childFrame = mainFrame->firstChild();
ASSERT_TRUE(childFrame);
registerMockedHttpURLLoad("white-1x1.png");
WebHistoryItem item;
item.initialize();
WebURL historyURL(toKURL(m_baseURL + "white-1x1.png"));
item.setURLString(historyURL.string());
mainFrame->loadHistoryItem(item);
childFrame->reload();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(item.urlString(), mainFrame->document().url().string());
EXPECT_EQ(item.urlString(), mainFrame->currentHistoryItem().urlString());
}
TEST_F(WebFrameTest, ReloadPost)
{
registerMockedHttpURLLoad("reload_post.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "reload_post.html", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), "javascript:document.forms[0].submit()");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_FALSE(frame->previousHistoryItem().isNull());
EXPECT_EQ(WebString::fromUTF8("POST"), frame->dataSource()->request().httpMethod());
frame->reload();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData, frame->dataSource()->request().cachePolicy());
EXPECT_EQ(WebNavigationTypeFormResubmitted, frame->dataSource()->navigationType());
}
TEST_F(WebFrameTest, LoadHistoryItemReload)
{
registerMockedHttpURLLoad("fragment_middle_click.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
WebHistoryItem firstItem = frame->currentHistoryItem();
EXPECT_FALSE(firstItem.isNull());
registerMockedHttpURLLoad("white-1x1.png");
FrameTestHelpers::loadFrame(frame, m_baseURL + "white-1x1.png");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_FALSE(frame->previousHistoryItem().isNull());
EXPECT_EQ(firstItem.urlString(), frame->previousHistoryItem().urlString());
frame->loadHistoryItem(frame->previousHistoryItem(), WebURLRequest::ReloadIgnoringCacheData);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(firstItem.urlString(), frame->currentHistoryItem().urlString());
EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData, frame->dataSource()->request().cachePolicy());
}
class TestCachePolicyWebFrameClient : public WebFrameClient {
public:
TestCachePolicyWebFrameClient()
: m_policy(WebURLRequest::UseProtocolCachePolicy)
, m_client(0)
, m_willSendRequestCallCount(0)
, m_childFrameCreationCount(0)
{
}
void setChildWebFrameClient(WebFrameClient* client) { m_client = client; }
WebURLRequest::CachePolicy cachePolicy() const { return m_policy; }
int willSendRequestCallCount() const { return m_willSendRequestCallCount; }
int childFrameCreationCount() const { return m_childFrameCreationCount; }
virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString&)
{
m_childFrameCreationCount++;
WebFrame* frame = WebFrame::create(m_client);
parent->appendChild(frame);
return frame;
}
virtual void frameDetached(WebFrame* frame) OVERRIDE
{
if (frame->parent())
frame->parent()->removeChild(frame);
frame->close();
}
virtual void willSendRequest(WebLocalFrame* frame, unsigned, WebURLRequest& request, const WebURLResponse&) OVERRIDE
{
m_policy = request.cachePolicy();
m_willSendRequestCallCount++;
}
private:
WebURLRequest::CachePolicy m_policy;
WebFrameClient* m_client;
int m_willSendRequestCallCount;
int m_childFrameCreationCount;
};
TEST_F(WebFrameTest, ReloadIframe)
{
registerMockedHttpURLLoad("iframe_reload.html");
registerMockedHttpURLLoad("visible_iframe.html");
TestCachePolicyWebFrameClient mainClient;
TestCachePolicyWebFrameClient childClient;
mainClient.setChildWebFrameClient(&childClient);
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, &mainClient);
WebFrameImpl* mainFrame = webViewHelper.webViewImpl()->mainFrameImpl();
RefPtr<WebFrameImpl> childFrame = toWebFrameImpl(mainFrame->firstChild());
ASSERT_EQ(childFrame->client(), &childClient);
EXPECT_EQ(mainClient.childFrameCreationCount(), 1);
EXPECT_EQ(childClient.willSendRequestCallCount(), 1);
EXPECT_EQ(childClient.cachePolicy(), WebURLRequest::UseProtocolCachePolicy);
mainFrame->reload(false);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
ASSERT_NE(childFrame, toWebFrameImpl(mainFrame->firstChild()));
ASSERT_EQ(toWebFrameImpl(mainFrame->firstChild())->client(), &childClient);
EXPECT_EQ(mainClient.childFrameCreationCount(), 2);
EXPECT_EQ(childClient.willSendRequestCallCount(), 2);
EXPECT_EQ(childClient.cachePolicy(), WebURLRequest::ReloadIgnoringCacheData);
}
TEST_F(WebFrameTest, ExportHistoryItemFromChildFrame)
{
registerMockedHttpURLLoad("iframe_reload.html");
registerMockedHttpURLLoad("visible_iframe.html");
TestCachePolicyWebFrameClient mainClient;
TestCachePolicyWebFrameClient childClient;
mainClient.setChildWebFrameClient(&childClient);
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true, &mainClient);
WebFrame* childFrame = webViewHelper.webViewImpl()->mainFrameImpl()->firstChild();
WebHistoryItem item = childFrame->currentHistoryItem();
EXPECT_EQ(item.urlString().utf8(), m_baseURL + "iframe_reload.html");
}
class TestSameDocumentWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
public:
TestSameDocumentWebFrameClient()
: m_frameLoadTypeSameSeen(false)
{
}
virtual void willSendRequest(WebLocalFrame* frame, unsigned, WebURLRequest&, const WebURLResponse&)
{
if (toWebFrameImpl(frame)->frame()->loader().loadType() == WebCore::FrameLoadTypeSame)
m_frameLoadTypeSameSeen = true;
}
bool frameLoadTypeSameSeen() const { return m_frameLoadTypeSameSeen; }
private:
bool m_frameLoadTypeSameSeen;
};
TEST_F(WebFrameTest, NavigateToSame)
{
registerMockedHttpURLLoad("navigate_to_same.html");
TestSameDocumentWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "navigate_to_same.html", true, &client);
EXPECT_FALSE(client.frameLoadTypeSameSeen());
WebCore::FrameLoadRequest frameRequest(0, WebCore::ResourceRequest(webViewHelper.webViewImpl()->page()->mainFrame()->document()->url()));
webViewHelper.webViewImpl()->page()->mainFrame()->loader().load(frameRequest);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_TRUE(client.frameLoadTypeSameSeen());
}
TEST_F(WebFrameTest, WebNodeImageContents)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank", true);
WebFrame* frame = webViewHelper.webView()->mainFrame();
static const char bluePNG[] = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYV2NkYPj/n4EIwDiqEF8oUT94AFIQE/cCn90IAAAAAElFTkSuQmCC\">";
WebCore::KURL testURL = toKURL("about:blank");
frame->loadHTMLString(bluePNG, testURL);
runPendingTasks();
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);
}
class TestStartStopCallbackWebFrameClient : public WebFrameClient {
public:
TestStartStopCallbackWebFrameClient()
: m_startLoadingCount(0)
, m_stopLoadingCount(0)
, m_differentDocumentStartCount(0)
{
}
virtual void didStartLoading(bool toDifferentDocument) OVERRIDE
{
m_startLoadingCount++;
if (toDifferentDocument)
m_differentDocumentStartCount++;
}
virtual void didStopLoading() OVERRIDE
{
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_F(WebFrameTest, PushStateStartsAndStops)
{
registerMockedHttpURLLoad("push_state.html");
TestStartStopCallbackWebFrameClient client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "push_state.html", true, &client);
runPendingTasks();
EXPECT_EQ(client.startLoadingCount(), 2);
EXPECT_EQ(client.stopLoadingCount(), 2);
EXPECT_EQ(client.differentDocumentStartCount(), 1);
}
class TestHistoryWebFrameClient : public WebFrameClient {
public:
TestHistoryWebFrameClient()
{
m_replacesCurrentHistoryItem = false;
m_frame = 0;
}
void didStartProvisionalLoad(WebLocalFrame* frame)
{
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;
};
TEST_F(WebFrameTest, DISABLED_FirstFrameNavigationReplacesHistory)
{
registerMockedHttpURLLoad("history.html");
registerMockedHttpURLLoad("find.html");
FrameTestHelpers::WebViewHelper webViewHelper;
TestHistoryWebFrameClient client;
webViewHelper.initializeAndLoad("about:blank", true, &client);
runPendingTasks();
EXPECT_TRUE(client.replacesCurrentHistoryItem());
WebFrame* frame = webViewHelper.webView()->mainFrame();
FrameTestHelpers::loadFrame(frame,
"javascript:document.body.appendChild(document.createElement('iframe'))");
runPendingTasks();
WebFrame* iframe = frame->firstChild();
EXPECT_EQ(client.frame(), iframe);
EXPECT_TRUE(client.replacesCurrentHistoryItem());
FrameTestHelpers::loadFrame(frame,
"javascript:window.frames[0].location.assign('" + m_baseURL + "history.html')");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(client.frame(), iframe);
EXPECT_TRUE(client.replacesCurrentHistoryItem());
FrameTestHelpers::loadFrame(frame,
"javascript:window.frames[0].location.assign('" + m_baseURL + "find.html')");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(client.frame(), iframe);
EXPECT_FALSE(client.replacesCurrentHistoryItem());
FrameTestHelpers::loadFrame(frame,
"javascript:var f = document.createElement('iframe'); "
"f.src = '" + m_baseURL + "history.html';"
"document.body.appendChild(f)");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
iframe = frame->firstChild()->nextSibling();
EXPECT_EQ(client.frame(), iframe);
EXPECT_TRUE(client.replacesCurrentHistoryItem());
FrameTestHelpers::loadFrame(frame,
"javascript:window.frames[1].location.assign('" + m_baseURL + "find.html')");
runPendingTasks();
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(client.frame(), iframe);
EXPECT_FALSE(client.replacesCurrentHistoryItem());
}
TEST_F(WebFrameTest, firstNavigationIsHistoryWithBlankChild)
{
registerMockedHttpURLLoad("history.html");
FrameTestHelpers::WebViewHelper webViewHelper;
WebViewImpl* webView = webViewHelper.initialize();
ASSERT_TRUE(webView->mainFrame()->currentHistoryItem().isNull());
WebHistoryItem item;
item.initialize();
WebURL destinationURL(toKURL(m_baseURL + "history.html"));
item.setURLString(destinationURL.string());
item.setTarget(WebString::fromUTF8("expectedButMissingMainFrameName"));
WebHistoryItem childItem;
childItem.initialize();
childItem.setURLString("about:blank");
item.appendToChildren(childItem);
webView->mainFrame()->loadHistoryItem(item);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
EXPECT_EQ(destinationURL, webView->mainFrame()->document().url());
}
TEST_F(WebFrameTest, overflowHiddenRewrite)
{
registerMockedHttpURLLoad("non-scrollable.html");
TestMainFrameUserOrProgrammaticScrollFrameClient client;
OwnPtr<FakeCompositingWebViewClient> fakeCompositingWebViewClient = adoptPtr(new FakeCompositingWebViewClient());
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize(true, 0, fakeCompositingWebViewClient.get(), &configueCompositingWebView);
webViewHelper.webView()->resize(WebSize(100, 100));
FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(), m_baseURL + "non-scrollable.html");
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webViewHelper.webView()->layout();
WebCore::RenderLayerCompositor* compositor = webViewHelper.webViewImpl()->compositor();
ASSERT_TRUE(compositor->scrollLayer());
WebCore::GraphicsLayer* scrollLayer = compositor->scrollLayer();
WebLayer* webScrollLayer = scrollLayer->platformLayer();
ASSERT_FALSE(webScrollLayer->userScrollableHorizontal());
ASSERT_FALSE(webScrollLayer->userScrollableVertical());
WebFrameImpl* frame = (WebFrameImpl*)webViewHelper.webView()->mainFrame();
frame->executeScript(WebScriptSource("allowScroll();"));
webViewHelper.webView()->layout();
ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
ASSERT_TRUE(webScrollLayer->userScrollableVertical());
}
TEST_F(WebFrameTest, CurrentHistoryItem)
{
registerMockedHttpURLLoad("fixed_layout.html");
std::string url = m_baseURL + "fixed_layout.html";
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initialize();
WebFrame* frame = webViewHelper.webView()->mainFrame();
FrameTestHelpers::loadFrame(frame, url);
EXPECT_TRUE(frame->currentHistoryItem().isNull());
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
WebHistoryItem item = frame->currentHistoryItem();
ASSERT_FALSE(item.isNull());
EXPECT_EQ(url, item.urlString().utf8());
}
class FailCreateChildFrame : public WebFrameClient {
public:
FailCreateChildFrame() : m_callCount(0) { }
virtual WebFrame* createChildFrame(WebLocalFrame* parent, const WebString& frameName) OVERRIDE
{
++m_callCount;
return 0;
}
virtual void frameDetached(WebFrame* frame) OVERRIDE
{
frame->close();
}
int callCount() const { return m_callCount; }
private:
int m_callCount;
};
TEST_F(WebFrameTest, CreateChildFrameFailure)
{
registerMockedHttpURLLoad("create_child_frame_fail.html");
FailCreateChildFrame client;
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "create_child_frame_fail.html", true, &client);
EXPECT_EQ(1, client.callCount());
}
TEST_F(WebFrameTest, DISABLED_sizeChangeRepaint)
{
const char* kTests[] = {
"repaint/size-change-repaint1.html",
"repaint/size-change-repaint2.html",
"repaint/size-change-repaint3.html",
"repaint/size-change-repaint4.html",
"repaint/size-change-repaint5.html",
"repaint/size-change-repaint6.html",
"repaint/size-change-repaint7.html",
"repaint/size-change-repaint8.html",
"repaint/size-change-repaint9.html",
"repaint/size-change-repaint10.html",
};
const WebCore::IntRect kExpectedRepaintOnHeightChange[] = {
WebCore::IntRect(0, 200, 200, 100),
WebCore::IntRect(0, 200, 200, 100),
WebCore::IntRect(0, 200, 200, 100),
WebCore::IntRect(0, 0, 200, 300),
WebCore::IntRect(0, 0, 200, 300),
WebCore::IntRect(0, 0, 200, 300),
WebCore::IntRect(0, 100, 200, 200),
WebCore::IntRect(0, 100, 200, 200),
WebCore::IntRect(0, 160, 200, 140),
WebCore::IntRect(0, 50, 200, 250),
};
const WebCore::IntRect kExpectedRepaintOnWidthChange[] = {
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
WebCore::IntRect(0, 0, 300, 300),
};
UseMockScrollbarSettings mockScrollbarSettings;
FrameTestHelpers::WebViewHelper webViewHelper;
WebViewImpl* webView = webViewHelper.initialize(true);
for (size_t i = 0; i < arraysize(kTests); ++i) {
SCOPED_TRACE(kTests[i]);
registerMockedHttpURLLoad(kTests[i]);
FrameTestHelpers::loadFrame(webView->mainFrame(), m_baseURL + kTests[i]);
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
webView->resize(WebSize(200, 200));
webView->layout();
WebCore::FrameView* frameView = webView->mainFrameImpl()->frameView();
frameView->setTracksRepaints(true);
webView->resize(WebSize(200, 300));
webView->layout();
WebCore::IntRect repaintRect = WebCore::intersection(WebCore::IntRect(0, 0, 200, 300), WebCore::unionRect(frameView->trackedRepaintRects()));
EXPECT_EQ_RECT(kExpectedRepaintOnHeightChange[i], repaintRect);
frameView->setTracksRepaints(true);
webView->resize(WebSize(300, 300));
webView->layout();
repaintRect = WebCore::intersection(WebCore::IntRect(0, 0, 300, 300), WebCore::unionRect(frameView->trackedRepaintRects()));
EXPECT_EQ_RECT(kExpectedRepaintOnWidthChange[i], repaintRect);
frameView->setTracksRepaints(false);
}
}
TEST_F(WebFrameTest, fixedPositionInFixedViewport)
{
UseMockScrollbarSettings mockScrollbarSettings;
registerMockedHttpURLLoad("fixed-position-in-fixed-viewport.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "fixed-position-in-fixed-viewport.html", true, 0, 0, enableViewportSettings);
WebView* webView = webViewHelper.webView();
webView->resize(WebSize(100, 100));
webView->layout();
Document* document = toWebFrameImpl(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");
webView->resize(WebSize(100, 200));
webView->layout();
EXPECT_EQ(200, bottomFixed->offsetTop() + bottomFixed->offsetHeight());
EXPECT_EQ(200, topBottomFixed->offsetHeight());
webView->settings()->setMainFrameResizesAreOrientationChanges(false);
webView->resize(WebSize(200, 200));
webView->layout();
EXPECT_EQ(200, rightFixed->offsetLeft() + rightFixed->offsetWidth());
EXPECT_EQ(200, leftRightFixed->offsetWidth());
webView->settings()->setMainFrameResizesAreOrientationChanges(true);
webView->resize(WebSize(300, 330));
webView->layout();
EXPECT_EQ(220, bottomFixed->offsetTop() + bottomFixed->offsetHeight());
EXPECT_EQ(220, topBottomFixed->offsetHeight());
EXPECT_EQ(200, rightFixed->offsetLeft() + rightFixed->offsetWidth());
EXPECT_EQ(200, leftRightFixed->offsetWidth());
}
TEST_F(WebFrameTest, FrameViewSetFrameRect)
{
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad("about:blank");
WebCore::FrameView* frameView = webViewHelper.webViewImpl()->mainFrameImpl()->frameView();
frameView->setFrameRect(WebCore::IntRect(0, 0, 200, 200));
EXPECT_EQ_RECT(WebCore::IntRect(0, 0, 200, 200), frameView->frameRect());
frameView->setFrameRect(WebCore::IntRect(100, 100, 200, 200));
EXPECT_EQ_RECT(WebCore::IntRect(100, 100, 200, 200), frameView->frameRect());
}
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, 0, &client, &configueCompositingWebView);
webViewImpl->resize(WebSize(viewportWidth, viewportHeight));
webViewImpl->layout();
Document* document = toWebFrameImpl(webViewImpl->mainFrame())->frame()->document();
WebCore::UserGestureIndicator gesture(WebCore::DefinitelyProcessingUserGesture);
Element* divFullscreen = document->getElementById("div1");
divFullscreen->webkitRequestFullscreen();
webViewImpl->willEnterFullScreen();
webViewImpl->didEnterFullScreen();
webViewImpl->layout();
ASSERT_TRUE(WebCore::FullscreenElementStack::isFullScreen(*document));
WebLayer* webScrollLayer = webViewImpl->compositor()->scrollLayer()->platformLayer();
ASSERT_FALSE(webScrollLayer->scrollable());
webViewImpl->willExitFullScreen();
webViewImpl->didExitFullScreen();
webViewImpl->layout();
ASSERT_FALSE(WebCore::FullscreenElementStack::isFullScreen(*document));
webScrollLayer = webViewImpl->compositor()->scrollLayer()->platformLayer();
ASSERT_TRUE(webScrollLayer->scrollable());
}
TEST_F(WebFrameTest, RenderBlockPercentHeightDescendants)
{
registerMockedHttpURLLoad("percent-height-descendants.html");
FrameTestHelpers::WebViewHelper webViewHelper;
webViewHelper.initializeAndLoad(m_baseURL + "percent-height-descendants.html");
WebView* webView = webViewHelper.webView();
webView->resize(WebSize(800, 800));
webView->layout();
Document* document = toWebFrameImpl(webView->mainFrame())->frame()->document();
WebCore::RenderBlock* container = WebCore::toRenderBlock(document->getElementById("container")->renderer());
WebCore::RenderBox* percentHeightInAnonymous = WebCore::toRenderBox(document->getElementById("percent-height-in-anonymous")->renderer());
WebCore::RenderBox* percentHeightDirectChild = WebCore::toRenderBox(document->getElementById("percent-height-direct-child")->renderer());
EXPECT_TRUE(WebCore::RenderBlock::hasPercentHeightDescendant(percentHeightInAnonymous));
EXPECT_TRUE(WebCore::RenderBlock::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));
WebCore::RenderBlock* anonymousBlock = percentHeightInAnonymous->containingBlock();
EXPECT_TRUE(anonymousBlock->isAnonymous());
EXPECT_FALSE(anonymousBlock->hasPercentHeightDescendants());
}
}