2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "public/web/WebFrame.h"
36 #include "bindings/core/v8/SerializedScriptValueFactory.h"
37 #include "bindings/core/v8/V8Node.h"
38 #include "core/clipboard/DataTransfer.h"
39 #include "core/css/StyleSheetContents.h"
40 #include "core/css/resolver/StyleResolver.h"
41 #include "core/css/resolver/ViewportStyleResolver.h"
42 #include "core/dom/Fullscreen.h"
43 #include "core/dom/NodeComputedStyle.h"
44 #include "core/dom/Range.h"
45 #include "core/editing/Editor.h"
46 #include "core/editing/EphemeralRange.h"
47 #include "core/editing/FrameSelection.h"
48 #include "core/editing/VisiblePosition.h"
49 #include "core/editing/markers/DocumentMarkerController.h"
50 #include "core/editing/spellcheck/SpellChecker.h"
51 #include "core/events/MouseEvent.h"
52 #include "core/fetch/FetchRequest.h"
53 #include "core/fetch/MemoryCache.h"
54 #include "core/fetch/ResourceFetcher.h"
55 #include "core/frame/FrameHost.h"
56 #include "core/frame/FrameView.h"
57 #include "core/frame/LocalFrame.h"
58 #include "core/frame/RemoteFrame.h"
59 #include "core/frame/Settings.h"
60 #include "core/frame/VisualViewport.h"
61 #include "core/html/HTMLDocument.h"
62 #include "core/html/HTMLFormElement.h"
63 #include "core/html/HTMLMediaElement.h"
64 #include "core/input/EventHandler.h"
65 #include "core/layout/HitTestResult.h"
66 #include "core/layout/LayoutFullScreen.h"
67 #include "core/layout/LayoutView.h"
68 #include "core/layout/compositing/DeprecatedPaintLayerCompositor.h"
69 #include "core/loader/DocumentLoader.h"
70 #include "core/loader/DocumentThreadableLoader.h"
71 #include "core/loader/DocumentThreadableLoaderClient.h"
72 #include "core/loader/FrameLoadRequest.h"
73 #include "core/loader/ThreadableLoader.h"
74 #include "core/page/Page.h"
75 #include "core/paint/DeprecatedPaintLayer.h"
76 #include "core/testing/NullExecutionContext.h"
77 #include "modules/mediastream/MediaStream.h"
78 #include "modules/mediastream/MediaStreamRegistry.h"
79 #include "platform/DragImage.h"
80 #include "platform/PlatformResourceLoader.h"
81 #include "platform/RuntimeEnabledFeatures.h"
82 #include "platform/UserGestureIndicator.h"
83 #include "platform/geometry/FloatRect.h"
84 #include "platform/network/ResourceError.h"
85 #include "platform/scroll/ScrollbarTheme.h"
86 #include "platform/testing/URLTestHelpers.h"
87 #include "platform/testing/UnitTestHelpers.h"
88 #include "platform/weborigin/SchemeRegistry.h"
89 #include "platform/weborigin/SecurityOrigin.h"
90 #include "public/platform/Platform.h"
91 #include "public/platform/WebFloatRect.h"
92 #include "public/platform/WebSecurityOrigin.h"
93 #include "public/platform/WebThread.h"
94 #include "public/platform/WebURL.h"
95 #include "public/platform/WebURLResponse.h"
96 #include "public/platform/WebUnitTestSupport.h"
97 #include "public/web/WebCache.h"
98 #include "public/web/WebConsoleMessage.h"
99 #include "public/web/WebDataSource.h"
100 #include "public/web/WebDeviceEmulationParams.h"
101 #include "public/web/WebDocument.h"
102 #include "public/web/WebFindOptions.h"
103 #include "public/web/WebFormElement.h"
104 #include "public/web/WebFrameClient.h"
105 #include "public/web/WebFrameWidget.h"
106 #include "public/web/WebHistoryItem.h"
107 #include "public/web/WebPrintParams.h"
108 #include "public/web/WebRange.h"
109 #include "public/web/WebRemoteFrame.h"
110 #include "public/web/WebScriptExecutionCallback.h"
111 #include "public/web/WebScriptSource.h"
112 #include "public/web/WebSearchableFormData.h"
113 #include "public/web/WebSecurityPolicy.h"
114 #include "public/web/WebSelection.h"
115 #include "public/web/WebSettings.h"
116 #include "public/web/WebSpellCheckClient.h"
117 #include "public/web/WebTextCheckingCompletion.h"
118 #include "public/web/WebTextCheckingResult.h"
119 #include "public/web/WebViewClient.h"
120 #include "web/WebLocalFrameImpl.h"
121 #include "web/WebRemoteFrameImpl.h"
122 #include "web/WebViewImpl.h"
123 #include "web/tests/FrameTestHelpers.h"
124 #include "wtf/Forward.h"
125 #include "wtf/dtoa/utils.h"
126 #include <gmock/gmock.h>
127 #include <gtest/gtest.h>
132 using blink::URLTestHelpers::toKURL
;
133 using blink::FrameTestHelpers::UseMockScrollbarSettings
;
134 using blink::testing::runPendingTasks
;
135 using testing::ElementsAre
;
141 ::std::ostream
& operator<<(::std::ostream
& os
, const WebFloatSize
& size
)
143 return os
<< "WebFloatSize: ["
144 << size
.width
<< ", " << size
.height
<< "]";
147 ::std::ostream
& operator<<(::std::ostream
& os
, const WebFloatPoint
& point
)
149 return os
<< "WebFloatPoint: ["
150 << point
.x
<< ", " << point
.y
<< "]";
153 const int touchPointPadding
= 32;
155 #define EXPECT_RECT_EQ(expected, actual) \
157 EXPECT_EQ(expected.x(), actual.x()); \
158 EXPECT_EQ(expected.y(), actual.y()); \
159 EXPECT_EQ(expected.width(), actual.width()); \
160 EXPECT_EQ(expected.height(), actual.height()); \
163 #define EXPECT_POINT_EQ(expected, actual) \
165 EXPECT_EQ(expected.x(), actual.x()); \
166 EXPECT_EQ(expected.y(), actual.y()); \
169 #define EXPECT_FLOAT_POINT_EQ(expected, actual) \
171 EXPECT_FLOAT_EQ(expected.x(), actual.x()); \
172 EXPECT_FLOAT_EQ(expected.y(), actual.y()); \
175 class WebFrameTest
: public ::testing::Test
{
178 : m_baseURL("http://internal.test/")
179 , m_notBaseURL("http://external.test/")
180 , m_chromeURL("chrome://")
184 ~WebFrameTest() override
186 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
189 void registerMockedHttpURLLoad(const std::string
& fileName
)
191 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL
.c_str()), WebString::fromUTF8(fileName
.c_str()));
194 void registerMockedChromeURLLoad(const std::string
& fileName
)
196 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_chromeURL
.c_str()), WebString::fromUTF8(fileName
.c_str()));
200 void registerMockedHttpURLLoadWithCSP(const std::string
& fileName
, const std::string
& csp
, bool reportOnly
= false)
202 WebURLResponse response
;
203 response
.initialize();
204 response
.setMIMEType("text/html");
205 response
.addHTTPHeaderField(reportOnly
? WebString("Content-Security-Policy-Report-Only") : WebString("Content-Security-Policy"), WebString::fromUTF8(csp
));
206 std::string fullString
= m_baseURL
+ fileName
;
207 URLTestHelpers::registerMockedURLLoadWithCustomResponse(toKURL(fullString
.c_str()), WebString::fromUTF8(fileName
.c_str()), WebString::fromUTF8(""), response
);
210 void applyViewportStyleOverride(FrameTestHelpers::WebViewHelper
* webViewHelper
)
212 RefPtrWillBeRawPtr
<StyleSheetContents
> styleSheet
= StyleSheetContents::create(CSSParserContext(UASheetMode
, 0));
213 styleSheet
->parseString(loadResourceAsASCIIString("viewportAndroid.css"));
214 OwnPtrWillBeRawPtr
<RuleSet
> ruleSet
= RuleSet::create();
215 ruleSet
->addRulesFromSheet(styleSheet
.get(), MediaQueryEvaluator("screen"));
217 Document
* document
= toLocalFrame(webViewHelper
->webViewImpl()->page()->mainFrame())->document();
218 document
->ensureStyleResolver().viewportStyleResolver()->collectViewportRules(ruleSet
.get(), ViewportStyleResolver::UserAgentOrigin
);
219 document
->ensureStyleResolver().viewportStyleResolver()->resolve();
222 static void configueCompositingWebView(WebSettings
* settings
)
224 settings
->setAcceleratedCompositingEnabled(true);
225 settings
->setPreferCompositingToLCDTextEnabled(true);
228 static void configureAndroid(WebSettings
* settings
)
230 settings
->setViewportMetaEnabled(true);
231 settings
->setViewportEnabled(true);
232 settings
->setMainFrameResizesAreOrientationChanges(true);
233 settings
->setShrinksViewportContentToFit(true);
236 static void configureLoadsImagesAutomatically(WebSettings
* settings
)
238 settings
->setLoadsImagesAutomatically(true);
241 void initializeTextSelectionWebView(const std::string
& url
, FrameTestHelpers::WebViewHelper
* webViewHelper
)
243 webViewHelper
->initializeAndLoad(url
, true);
244 webViewHelper
->webView()->settings()->setDefaultFontSize(12);
245 webViewHelper
->webView()->resize(WebSize(640, 480));
248 PassOwnPtr
<DragImage
> nodeImageTestSetup(FrameTestHelpers::WebViewHelper
* webViewHelper
, const std::string
& testcase
)
250 registerMockedHttpURLLoad("nodeimage.html");
251 webViewHelper
->initializeAndLoad(m_baseURL
+ "nodeimage.html");
252 webViewHelper
->webView()->resize(WebSize(640, 480));
253 webViewHelper
->webView()->layout();
254 RefPtrWillBeRawPtr
<LocalFrame
> frame
= toLocalFrame(webViewHelper
->webViewImpl()->page()->mainFrame());
256 Element
* element
= frame
->document()->getElementById(testcase
.c_str());
257 return frame
->nodeImage(*element
);
260 void removeElementById(WebLocalFrameImpl
* frame
, const AtomicString
& id
)
262 Element
* element
= frame
->frame()->document()->getElementById(id
);
267 std::string m_baseURL
;
268 std::string m_notBaseURL
;
269 std::string m_chromeURL
;
272 enum ParameterizedWebFrameTestConfig
{
277 class ParameterizedWebFrameTest
278 : public WebFrameTest
279 , public ::testing::WithParamInterface
<ParameterizedWebFrameTestConfig
>
280 , public FrameTestHelpers::SettingOverrider
{
283 void overrideSettings(WebSettings
* settings
)
285 switch (GetParam()) {
288 case RootLayerScrolls
:
289 settings
->setRootLayerScrolls(true);
295 // Friendly string for gtest failure messages.
296 void PrintTo(ParameterizedWebFrameTestConfig config
, ::std::ostream
* os
)
302 case RootLayerScrolls
:
303 *os
<< "RootLayerScrolls";
308 INSTANTIATE_TEST_CASE_P(All
, ParameterizedWebFrameTest
, ::testing::Values(
309 ParameterizedWebFrameTestConfig::Default
,
310 ParameterizedWebFrameTestConfig::RootLayerScrolls
));
312 TEST_P(ParameterizedWebFrameTest
, ContentText
)
314 registerMockedHttpURLLoad("iframes_test.html");
315 registerMockedHttpURLLoad("visible_iframe.html");
316 registerMockedHttpURLLoad("invisible_iframe.html");
317 registerMockedHttpURLLoad("zero_sized_iframe.html");
319 FrameTestHelpers::WebViewHelper
webViewHelper(this);
320 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframes_test.html");
322 // Now retrieve the frames text and test it only includes visible elements.
323 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
324 EXPECT_NE(std::string::npos
, content
.find(" visible paragraph"));
325 EXPECT_NE(std::string::npos
, content
.find(" visible iframe"));
326 EXPECT_EQ(std::string::npos
, content
.find(" invisible pararaph"));
327 EXPECT_EQ(std::string::npos
, content
.find(" invisible iframe"));
328 EXPECT_EQ(std::string::npos
, content
.find("iframe with zero size"));
331 TEST_P(ParameterizedWebFrameTest
, FrameForEnteredContext
)
333 registerMockedHttpURLLoad("iframes_test.html");
334 registerMockedHttpURLLoad("visible_iframe.html");
335 registerMockedHttpURLLoad("invisible_iframe.html");
336 registerMockedHttpURLLoad("zero_sized_iframe.html");
338 FrameTestHelpers::WebViewHelper
webViewHelper(this);
339 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframes_test.html", true);
341 v8::HandleScope
scope(v8::Isolate::GetCurrent());
342 EXPECT_EQ(webViewHelper
.webView()->mainFrame(), WebLocalFrame::frameForContext(webViewHelper
.webView()->mainFrame()->mainWorldScriptContext()));
343 EXPECT_EQ(webViewHelper
.webView()->mainFrame()->firstChild(), WebLocalFrame::frameForContext(webViewHelper
.webView()->mainFrame()->firstChild()->mainWorldScriptContext()));
346 class ScriptExecutionCallbackHelper
: public WebScriptExecutionCallback
{
348 explicit ScriptExecutionCallbackHelper(v8::Local
<v8::Context
> context
)
349 : m_didComplete(false)
350 , m_context(context
) { }
351 ~ScriptExecutionCallbackHelper() { }
353 bool didComplete() const { return m_didComplete
; }
354 const String
& stringValue() const { return m_stringValue
; }
357 void completed(const WebVector
<v8::Local
<v8::Value
>>& values
) override
359 m_didComplete
= true;
360 if (!values
.isEmpty() && values
[0]->IsString()) {
361 m_stringValue
= toCoreString(values
[0]->ToString(m_context
).ToLocalChecked());
366 String m_stringValue
;
367 v8::Local
<v8::Context
> m_context
;
370 TEST_P(ParameterizedWebFrameTest
, RequestExecuteScript
)
372 registerMockedHttpURLLoad("foo.html");
374 FrameTestHelpers::WebViewHelper
webViewHelper(this);
375 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html", true);
377 v8::HandleScope
scope(v8::Isolate::GetCurrent());
378 ScriptExecutionCallbackHelper
callbackHelper(webViewHelper
.webView()->mainFrame()->mainWorldScriptContext());
379 webViewHelper
.webView()->mainFrame()->toWebLocalFrame()->requestExecuteScriptAndReturnValue(WebScriptSource(WebString("'hello';")), false, &callbackHelper
);
381 EXPECT_TRUE(callbackHelper
.didComplete());
382 EXPECT_EQ("hello", callbackHelper
.stringValue());
385 TEST_P(ParameterizedWebFrameTest
, SuspendedRequestExecuteScript
)
387 registerMockedHttpURLLoad("foo.html");
388 registerMockedHttpURLLoad("bar.html");
390 FrameTestHelpers::WebViewHelper
webViewHelper(this);
391 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html", true);
393 v8::HandleScope
scope(v8::Isolate::GetCurrent());
394 ScriptExecutionCallbackHelper
callbackHelper(webViewHelper
.webView()->mainFrame()->mainWorldScriptContext());
396 // Suspend scheduled tasks so the script doesn't run.
397 toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame())->frame()->document()->suspendScheduledTasks();
398 webViewHelper
.webView()->mainFrame()->toWebLocalFrame()->requestExecuteScriptAndReturnValue(WebScriptSource(WebString("'hello';")), false, &callbackHelper
);
400 EXPECT_FALSE(callbackHelper
.didComplete());
402 // If the frame navigates, pending scripts should be removed, but the callback should always be ran.
403 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "bar.html");
404 EXPECT_TRUE(callbackHelper
.didComplete());
405 EXPECT_EQ(String(), callbackHelper
.stringValue());
408 TEST_P(ParameterizedWebFrameTest
, IframeScriptRemovesSelf
)
410 registerMockedHttpURLLoad("single_iframe.html");
411 registerMockedHttpURLLoad("visible_iframe.html");
413 FrameTestHelpers::WebViewHelper
webViewHelper(this);
414 webViewHelper
.initializeAndLoad(m_baseURL
+ "single_iframe.html", true);
416 v8::HandleScope
scope(v8::Isolate::GetCurrent());
417 ScriptExecutionCallbackHelper
callbackHelper(webViewHelper
.webView()->mainFrame()->mainWorldScriptContext());
418 webViewHelper
.webView()->mainFrame()->firstChild()->toWebLocalFrame()->requestExecuteScriptAndReturnValue(WebScriptSource(WebString("var iframe = window.top.document.getElementsByTagName('iframe')[0]; window.top.document.body.removeChild(iframe); 'hello';")), false, &callbackHelper
);
420 EXPECT_TRUE(callbackHelper
.didComplete());
421 EXPECT_EQ(String(), callbackHelper
.stringValue());
424 TEST_P(ParameterizedWebFrameTest
, FormWithNullFrame
)
426 registerMockedHttpURLLoad("form.html");
428 FrameTestHelpers::WebViewHelper
webViewHelper(this);
429 webViewHelper
.initializeAndLoad(m_baseURL
+ "form.html");
431 WebVector
<WebFormElement
> forms
;
432 webViewHelper
.webView()->mainFrame()->document().forms(forms
);
433 webViewHelper
.reset();
435 EXPECT_EQ(forms
.size(), 1U);
437 // This test passes if this doesn't crash.
438 WebSearchableFormData
searchableDataForm(forms
[0]);
441 TEST_P(ParameterizedWebFrameTest
, ChromePageJavascript
)
443 registerMockedChromeURLLoad("history.html");
445 // Pass true to enable JavaScript.
446 FrameTestHelpers::WebViewHelper
webViewHelper(this);
447 webViewHelper
.initializeAndLoad(m_chromeURL
+ "history.html", true);
449 // Try to run JS against the chrome-style URL.
450 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
452 // Required to see any updates in contentAsText.
453 webViewHelper
.webView()->layout();
455 // Now retrieve the frame's text and ensure it was modified by running javascript.
456 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
457 EXPECT_NE(std::string::npos
, content
.find("Clobbered"));
460 TEST_P(ParameterizedWebFrameTest
, ChromePageNoJavascript
)
462 registerMockedChromeURLLoad("history.html");
464 /// Pass true to enable JavaScript.
465 FrameTestHelpers::WebViewHelper
webViewHelper(this);
466 webViewHelper
.initializeAndLoad(m_chromeURL
+ "history.html", true);
468 // Try to run JS against the chrome-style URL after prohibiting it.
469 WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs("chrome");
470 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Clobbered'))");
472 // Required to see any updates in contentAsText.
473 webViewHelper
.webView()->layout();
475 // Now retrieve the frame's text and ensure it wasn't modified by running javascript.
476 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
477 EXPECT_EQ(std::string::npos
, content
.find("Clobbered"));
480 TEST_P(ParameterizedWebFrameTest
, LocationSetHostWithMissingPort
)
482 std::string fileName
= "print-location-href.html";
483 registerMockedHttpURLLoad(fileName
);
484 URLTestHelpers::registerMockedURLLoad(toKURL("http://internal.test:0/" + fileName
), WebString::fromUTF8(fileName
));
486 FrameTestHelpers::WebViewHelper
webViewHelper(this);
488 /// Pass true to enable JavaScript.
489 webViewHelper
.initializeAndLoad(m_baseURL
+ fileName
, true);
491 // Setting host to "hostname:" should be treated as "hostname:0".
492 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:location.host = 'internal.test:'; void 0;");
494 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
496 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
497 EXPECT_EQ("http://internal.test:0/" + fileName
, content
);
500 TEST_P(ParameterizedWebFrameTest
, LocationSetEmptyPort
)
502 std::string fileName
= "print-location-href.html";
503 registerMockedHttpURLLoad(fileName
);
504 URLTestHelpers::registerMockedURLLoad(toKURL("http://internal.test:0/" + fileName
), WebString::fromUTF8(fileName
));
506 FrameTestHelpers::WebViewHelper
webViewHelper(this);
508 /// Pass true to enable JavaScript.
509 webViewHelper
.initializeAndLoad(m_baseURL
+ fileName
, true);
511 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:location.port = ''; void 0;");
513 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.body.textContent = location.href; void 0;");
515 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
516 EXPECT_EQ("http://internal.test:0/" + fileName
, content
);
519 class EvaluateOnLoadWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
521 EvaluateOnLoadWebFrameClient() : m_executing(false), m_wasExecuted(false) { }
523 void didClearWindowObject(WebLocalFrame
* frame
) override
525 EXPECT_FALSE(m_executing
);
526 m_wasExecuted
= true;
528 v8::HandleScope
handleScope(v8::Isolate::GetCurrent());
529 frame
->executeScriptAndReturnValue(WebScriptSource(WebString("window.someProperty = 42;")));
537 TEST_P(ParameterizedWebFrameTest
, DidClearWindowObjectIsNotRecursive
)
539 EvaluateOnLoadWebFrameClient webFrameClient
;
540 FrameTestHelpers::WebViewHelper
webViewHelper(this);
541 webViewHelper
.initializeAndLoad("about:blank", true, &webFrameClient
);
542 EXPECT_TRUE(webFrameClient
.m_wasExecuted
);
545 class CSSCallbackWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
547 CSSCallbackWebFrameClient() : m_updateCount(0) { }
548 void didMatchCSS(WebLocalFrame
*, const WebVector
<WebString
>& newlyMatchingSelectors
, const WebVector
<WebString
>& stoppedMatchingSelectors
) override
;
550 std::map
<WebLocalFrame
*, std::set
<std::string
>> m_matchedSelectors
;
554 void CSSCallbackWebFrameClient::didMatchCSS(WebLocalFrame
* frame
, const WebVector
<WebString
>& newlyMatchingSelectors
, const WebVector
<WebString
>& stoppedMatchingSelectors
)
557 std::set
<std::string
>& frameSelectors
= m_matchedSelectors
[frame
];
558 for (size_t i
= 0; i
< newlyMatchingSelectors
.size(); ++i
) {
559 std::string selector
= newlyMatchingSelectors
[i
].utf8();
560 EXPECT_EQ(0U, frameSelectors
.count(selector
)) << selector
;
561 frameSelectors
.insert(selector
);
563 for (size_t i
= 0; i
< stoppedMatchingSelectors
.size(); ++i
) {
564 std::string selector
= stoppedMatchingSelectors
[i
].utf8();
565 EXPECT_EQ(1U, frameSelectors
.count(selector
)) << selector
;
566 frameSelectors
.erase(selector
);
570 class WebFrameCSSCallbackTest
: public ::testing::Test
{
572 WebFrameCSSCallbackTest()
574 m_frame
= m_helper
.initializeAndLoad("about:blank", true, &m_client
)->mainFrame()->toWebLocalFrame();
577 ~WebFrameCSSCallbackTest()
579 EXPECT_EQ(1U, m_client
.m_matchedSelectors
.size());
582 WebDocument
doc() const
584 return m_frame
->document();
587 int updateCount() const
589 return m_client
.m_updateCount
;
592 const std::set
<std::string
>& matchedSelectors()
594 return m_client
.m_matchedSelectors
[m_frame
];
597 void loadHTML(const std::string
& html
)
599 FrameTestHelpers::loadHTMLString(m_frame
, html
, toKURL("about:blank"));
602 void executeScript(const WebString
& code
)
604 m_frame
->executeScript(WebScriptSource(code
));
605 m_frame
->view()->layout();
609 CSSCallbackWebFrameClient m_client
;
610 FrameTestHelpers::WebViewHelper m_helper
;
611 WebLocalFrame
* m_frame
;
614 TEST_F(WebFrameCSSCallbackTest
, AuthorStyleSheet
)
618 // This stylesheet checks that the internal property and value can't be
619 // set by a stylesheet, only WebDocument::watchCSSSelectors().
620 "div.initial_on { -internal-callback: none; }"
621 "div.initial_off { -internal-callback: -internal-presence; }"
623 "<div class=\"initial_on\"></div>"
624 "<div class=\"initial_off\"></div>");
626 std::vector
<WebString
> selectors
;
627 selectors
.push_back(WebString::fromUTF8("div.initial_on"));
628 m_frame
->document().watchCSSSelectors(WebVector
<WebString
>(selectors
));
629 m_frame
->view()->layout();
631 EXPECT_EQ(1, updateCount());
632 EXPECT_THAT(matchedSelectors(), ElementsAre("div.initial_on"));
634 // Check that adding a watched selector calls back for already-present nodes.
635 selectors
.push_back(WebString::fromUTF8("div.initial_off"));
636 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
637 m_frame
->view()->layout();
639 EXPECT_EQ(2, updateCount());
640 EXPECT_THAT(matchedSelectors(), ElementsAre("div.initial_off", "div.initial_on"));
642 // Check that we can turn off callbacks for certain selectors.
643 doc().watchCSSSelectors(WebVector
<WebString
>());
644 m_frame
->view()->layout();
646 EXPECT_EQ(3, updateCount());
647 EXPECT_THAT(matchedSelectors(), ElementsAre());
650 TEST_F(WebFrameCSSCallbackTest
, SharedComputedStyle
)
652 // Check that adding an element calls back when it matches an existing rule.
653 std::vector
<WebString
> selectors
;
654 selectors
.push_back(WebString::fromUTF8("span"));
655 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
658 "i1 = document.createElement('span');"
659 "i1.id = 'first_span';"
660 "document.body.appendChild(i1)");
661 EXPECT_EQ(1, updateCount());
662 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
664 // Adding a second element that shares a ComputedStyle shouldn't call back.
665 // We use <span>s to avoid default style rules that can set
666 // ComputedStyle::unique().
668 "i2 = document.createElement('span');"
669 "i2.id = 'second_span';"
670 "i1 = document.getElementById('first_span');"
671 "i1.parentNode.insertBefore(i2, i1.nextSibling);");
672 EXPECT_EQ(1, updateCount());
673 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
675 // Removing the first element shouldn't call back.
677 "i1 = document.getElementById('first_span');"
678 "i1.parentNode.removeChild(i1);");
679 EXPECT_EQ(1, updateCount());
680 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
682 // But removing the second element *should* call back.
684 "i2 = document.getElementById('second_span');"
685 "i2.parentNode.removeChild(i2);");
686 EXPECT_EQ(2, updateCount());
687 EXPECT_THAT(matchedSelectors(), ElementsAre());
690 TEST_F(WebFrameCSSCallbackTest
, CatchesAttributeChange
)
692 loadHTML("<span></span>");
694 std::vector
<WebString
> selectors
;
695 selectors
.push_back(WebString::fromUTF8("span[attr=\"value\"]"));
696 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
699 EXPECT_EQ(0, updateCount());
700 EXPECT_THAT(matchedSelectors(), ElementsAre());
703 "document.querySelector('span').setAttribute('attr', 'value');");
704 EXPECT_EQ(1, updateCount());
705 EXPECT_THAT(matchedSelectors(), ElementsAre("span[attr=\"value\"]"));
708 TEST_F(WebFrameCSSCallbackTest
, DisplayNone
)
710 loadHTML("<div style='display:none'><span></span></div>");
712 std::vector
<WebString
> selectors
;
713 selectors
.push_back(WebString::fromUTF8("span"));
714 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
717 EXPECT_EQ(0, updateCount()) << "Don't match elements in display:none trees.";
720 "d = document.querySelector('div');"
721 "d.style.display = 'block';");
722 EXPECT_EQ(1, updateCount()) << "Match elements when they become displayed.";
723 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
726 "d = document.querySelector('div');"
727 "d.style.display = 'none';");
728 EXPECT_EQ(2, updateCount()) << "Unmatch elements when they become undisplayed.";
729 EXPECT_THAT(matchedSelectors(), ElementsAre());
732 "s = document.querySelector('span');"
733 "s.style.display = 'none';");
734 EXPECT_EQ(2, updateCount()) << "No effect from no-display'ing a span that's already undisplayed.";
737 "d = document.querySelector('div');"
738 "d.style.display = 'block';");
739 EXPECT_EQ(2, updateCount()) << "No effect from displaying a div whose span is display:none.";
742 "s = document.querySelector('span');"
743 "s.style.display = 'inline';");
744 EXPECT_EQ(3, updateCount()) << "Now the span is visible and produces a callback.";
745 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
748 "s = document.querySelector('span');"
749 "s.style.display = 'none';");
750 EXPECT_EQ(4, updateCount()) << "Undisplaying the span directly should produce another callback.";
751 EXPECT_THAT(matchedSelectors(), ElementsAre());
754 TEST_F(WebFrameCSSCallbackTest
, Reparenting
)
757 "<div id='d1'><span></span></div>"
758 "<div id='d2'></div>");
760 std::vector
<WebString
> selectors
;
761 selectors
.push_back(WebString::fromUTF8("span"));
762 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
763 m_frame
->view()->layout();
766 EXPECT_EQ(1, updateCount());
767 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
770 "s = document.querySelector('span');"
771 "d2 = document.getElementById('d2');"
772 "d2.appendChild(s);");
773 EXPECT_EQ(1, updateCount()) << "Just moving an element that continues to match shouldn't send a spurious callback.";
774 EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
777 TEST_F(WebFrameCSSCallbackTest
, MultiSelector
)
779 loadHTML("<span></span>");
781 // Check that selector lists match as the whole list, not as each element
783 std::vector
<WebString
> selectors
;
784 selectors
.push_back(WebString::fromUTF8("span"));
785 selectors
.push_back(WebString::fromUTF8("span,p"));
786 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
787 m_frame
->view()->layout();
790 EXPECT_EQ(1, updateCount());
791 EXPECT_THAT(matchedSelectors(), ElementsAre("span", "span, p"));
794 TEST_F(WebFrameCSSCallbackTest
, InvalidSelector
)
796 loadHTML("<p><span></span></p>");
798 // Build a list with one valid selector and one invalid.
799 std::vector
<WebString
> selectors
;
800 selectors
.push_back(WebString::fromUTF8("span"));
801 selectors
.push_back(WebString::fromUTF8("[")); // Invalid.
802 selectors
.push_back(WebString::fromUTF8("p span")); // Not compound.
803 doc().watchCSSSelectors(WebVector
<WebString
>(selectors
));
804 m_frame
->view()->layout();
807 EXPECT_EQ(1, updateCount());
808 EXPECT_THAT(matchedSelectors(), ElementsAre("span"))
809 << "An invalid selector shouldn't prevent other selectors from matching.";
812 TEST_P(ParameterizedWebFrameTest
, DispatchMessageEventWithOriginCheck
)
814 registerMockedHttpURLLoad("postmessage_test.html");
816 // Pass true to enable JavaScript.
817 FrameTestHelpers::WebViewHelper
webViewHelper(this);
818 webViewHelper
.initializeAndLoad(m_baseURL
+ "postmessage_test.html", true);
820 // Send a message with the correct origin.
821 WebSecurityOrigin
correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL
)));
822 WebDocument document
= webViewHelper
.webView()->mainFrame()->document();
823 WebDOMEvent event
= document
.createEvent("MessageEvent");
824 WebDOMMessageEvent message
= event
.to
<WebDOMMessageEvent
>();
825 WebSerializedScriptValue
data(WebSerializedScriptValue::fromString("foo"));
826 message
.initMessageEvent("message", false, false, data
, "http://origin.com", 0, document
, "");
827 webViewHelper
.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(correctOrigin
, message
);
829 // Send another message with incorrect origin.
830 WebSecurityOrigin
incorrectOrigin(WebSecurityOrigin::create(toKURL(m_chromeURL
)));
831 webViewHelper
.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(incorrectOrigin
, message
);
833 // Required to see any updates in contentAsText.
834 webViewHelper
.webView()->layout();
836 // Verify that only the first addition is in the body of the page.
837 std::string content
= webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
838 EXPECT_NE(std::string::npos
, content
.find("Message 1."));
839 EXPECT_EQ(std::string::npos
, content
.find("Message 2."));
842 TEST_P(ParameterizedWebFrameTest
, PostMessageThenDetach
)
844 FrameTestHelpers::WebViewHelper
webViewHelper(this);
845 webViewHelper
.initializeAndLoad("about:blank");
847 RefPtrWillBeRawPtr
<LocalFrame
> frame
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame());
848 NonThrowableExceptionState exceptionState
;
849 frame
->domWindow()->postMessage(SerializedScriptValueFactory::instance().create("message"), 0, "*", frame
->localDOMWindow(), exceptionState
);
850 webViewHelper
.reset();
851 EXPECT_FALSE(exceptionState
.hadException());
853 // Success is not crashing.
859 class FixedLayoutTestWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
861 WebScreenInfo
screenInfo() override
{ return m_screenInfo
; }
863 WebScreenInfo m_screenInfo
;
866 class FakeCompositingWebViewClient
: public FixedLayoutTestWebViewClient
{
869 // Viewport settings need to be set before the page gets loaded
870 void enableViewportSettings(WebSettings
* settings
)
872 settings
->setViewportMetaEnabled(true);
873 settings
->setViewportEnabled(true);
874 settings
->setMainFrameResizesAreOrientationChanges(true);
875 settings
->setShrinksViewportContentToFit(true);
878 // Helper function to set autosizing multipliers on a document.
879 bool setTextAutosizingMultiplier(Document
* document
, float multiplier
)
881 bool multiplierSet
= false;
882 for (LayoutObject
* layoutObject
= document
->layoutView(); layoutObject
; layoutObject
= layoutObject
->nextInPreOrder()) {
883 if (layoutObject
->style()) {
884 layoutObject
->mutableStyleRef().setTextAutosizingMultiplier(multiplier
);
886 EXPECT_EQ(multiplier
, layoutObject
->style()->textAutosizingMultiplier());
887 multiplierSet
= true;
890 return multiplierSet
;
893 // Helper function to check autosizing multipliers on a document.
894 bool checkTextAutosizingMultiplier(Document
* document
, float multiplier
)
896 bool multiplierChecked
= false;
897 for (LayoutObject
* layoutObject
= document
->layoutView(); layoutObject
; layoutObject
= layoutObject
->nextInPreOrder()) {
898 if (layoutObject
->style() && layoutObject
->isText()) {
899 EXPECT_EQ(multiplier
, layoutObject
->style()->textAutosizingMultiplier());
900 multiplierChecked
= true;
903 return multiplierChecked
;
906 } // anonymous namespace
908 TEST_P(ParameterizedWebFrameTest
, ChangeInFixedLayoutResetsTextAutosizingMultipliers
)
910 UseMockScrollbarSettings mockScrollbarSettings
;
911 registerMockedHttpURLLoad("fixed_layout.html");
913 FixedLayoutTestWebViewClient client
;
914 int viewportWidth
= 640;
915 int viewportHeight
= 480;
917 FrameTestHelpers::WebViewHelper
webViewHelper(this);
918 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
920 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
921 document
->settings()->setTextAutosizingEnabled(true);
922 EXPECT_TRUE(document
->settings()->textAutosizingEnabled());
923 webViewHelper
.webViewImpl()->resize(WebSize(viewportWidth
, viewportHeight
));
924 webViewHelper
.webViewImpl()->layout();
926 EXPECT_TRUE(setTextAutosizingMultiplier(document
, 2));
928 ViewportDescription description
= document
->viewportDescription();
929 // Choose a width that's not going match the viewport width of the loaded document.
930 description
.minWidth
= Length(100, blink::Fixed
);
931 description
.maxWidth
= Length(100, blink::Fixed
);
932 webViewHelper
.webViewImpl()->updatePageDefinedViewportConstraints(description
);
934 EXPECT_TRUE(checkTextAutosizingMultiplier(document
, 1));
937 TEST_P(ParameterizedWebFrameTest
, WorkingTextAutosizingMultipliers_VirtualViewport
)
939 UseMockScrollbarSettings mockScrollbarSettings
;
940 const std::string htmlFile
= "fixed_layout.html";
941 registerMockedHttpURLLoad(htmlFile
);
943 FixedLayoutTestWebViewClient client
;
945 FrameTestHelpers::WebViewHelper
webViewHelper(this);
946 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
, configureAndroid
);
948 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
949 document
->settings()->setTextAutosizingEnabled(true);
950 EXPECT_TRUE(document
->settings()->textAutosizingEnabled());
952 webViewHelper
.webView()->resize(WebSize(490, 800));
954 // Multiplier: 980 / 490 = 2.0
955 EXPECT_TRUE(checkTextAutosizingMultiplier(document
, 2.0));
958 TEST_P(ParameterizedWebFrameTest
, VisualViewportSetSizeInvalidatesTextAutosizingMultipliers
)
960 UseMockScrollbarSettings mockScrollbarSettings
;
961 registerMockedHttpURLLoad("iframe_reload.html");
962 registerMockedHttpURLLoad("visible_iframe.html");
964 FixedLayoutTestWebViewClient client
;
965 int viewportWidth
= 640;
966 int viewportHeight
= 480;
968 FrameTestHelpers::WebViewHelper
webViewHelper(this);
969 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframe_reload.html", true, 0, &client
, enableViewportSettings
);
971 LocalFrame
* mainFrame
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame());
972 Document
* document
= mainFrame
->document();
973 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
974 document
->settings()->setTextAutosizingEnabled(true);
975 EXPECT_TRUE(document
->settings()->textAutosizingEnabled());
976 webViewHelper
.webViewImpl()->resize(WebSize(viewportWidth
, viewportHeight
));
977 webViewHelper
.webViewImpl()->layout();
979 for (Frame
* frame
= mainFrame
; frame
; frame
= frame
->tree().traverseNext()) {
980 if (!frame
->isLocalFrame())
982 EXPECT_TRUE(setTextAutosizingMultiplier(toLocalFrame(frame
)->document(), 2));
983 for (LayoutObject
* layoutObject
= toLocalFrame(frame
)->document()->layoutView(); layoutObject
; layoutObject
= layoutObject
->nextInPreOrder()) {
984 if (layoutObject
->isText())
985 EXPECT_FALSE(layoutObject
->needsLayout());
989 frameView
->page()->frameHost().visualViewport().setSize(IntSize(200, 200));
991 for (Frame
* frame
= mainFrame
; frame
; frame
= frame
->tree().traverseNext()) {
992 if (!frame
->isLocalFrame())
994 for (LayoutObject
* layoutObject
= toLocalFrame(frame
)->document()->layoutView(); layoutObject
; layoutObject
= layoutObject
->nextInPreOrder()) {
995 if (layoutObject
->isText())
996 EXPECT_TRUE(layoutObject
->needsLayout());
1001 TEST_P(ParameterizedWebFrameTest
, ZeroHeightPositiveWidthNotIgnored
)
1003 UseMockScrollbarSettings mockScrollbarSettings
;
1005 FixedLayoutTestWebViewClient client
;
1006 client
.m_screenInfo
.deviceScaleFactor
= 1;
1007 int viewportWidth
= 1280;
1008 int viewportHeight
= 0;
1010 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1011 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1012 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1014 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1015 EXPECT_EQ(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1018 TEST_P(ParameterizedWebFrameTest
, DeviceScaleFactorUsesDefaultWithoutViewportTag
)
1020 UseMockScrollbarSettings mockScrollbarSettings
;
1021 registerMockedHttpURLLoad("no_viewport_tag.html");
1023 int viewportWidth
= 640;
1024 int viewportHeight
= 480;
1026 FixedLayoutTestWebViewClient client
;
1027 client
.m_screenInfo
.deviceScaleFactor
= 2;
1029 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1030 webViewHelper
.initializeAndLoad(m_baseURL
+ "no_viewport_tag.html", true, 0, &client
, enableViewportSettings
);
1032 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1033 webViewHelper
.webView()->layout();
1035 EXPECT_EQ(2, webViewHelper
.webView()->deviceScaleFactor());
1037 // Device scale factor should be independent of page scale.
1038 webViewHelper
.webView()->setDefaultPageScaleLimits(1, 2);
1039 webViewHelper
.webView()->setPageScaleFactor(0.5);
1040 webViewHelper
.webView()->layout();
1041 EXPECT_EQ(1, webViewHelper
.webView()->pageScaleFactor());
1043 // Force the layout to happen before leaving the test.
1044 webViewHelper
.webView()->mainFrame()->contentAsText(1024).utf8();
1047 TEST_P(ParameterizedWebFrameTest
, FixedLayoutInitializeAtMinimumScale
)
1049 UseMockScrollbarSettings mockScrollbarSettings
;
1051 registerMockedHttpURLLoad("fixed_layout.html");
1053 FixedLayoutTestWebViewClient client
;
1054 client
.m_screenInfo
.deviceScaleFactor
= 1;
1055 int viewportWidth
= 640;
1056 int viewportHeight
= 480;
1058 // Make sure we initialize to minimum scale, even if the window size
1059 // only becomes available after the load begins.
1060 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1061 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1062 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
1063 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "fixed_layout.html");
1064 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1066 int defaultFixedLayoutWidth
= 980;
1067 float minimumPageScaleFactor
= viewportWidth
/ (float) defaultFixedLayoutWidth
;
1068 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
1069 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
1071 // Assume the user has pinch zoomed to page scale factor 2.
1072 float userPinchPageScaleFactor
= 2;
1073 webViewHelper
.webView()->setPageScaleFactor(userPinchPageScaleFactor
);
1074 webViewHelper
.webView()->layout();
1076 // Make sure we don't reset to initial scale if the page continues to load.
1077 webViewHelper
.webViewImpl()->didCommitLoad(false, false);
1078 webViewHelper
.webViewImpl()->didChangeContentsSize();
1079 EXPECT_EQ(userPinchPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1081 // Make sure we don't reset to initial scale if the viewport size changes.
1082 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
+ 100));
1083 EXPECT_EQ(userPinchPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1086 TEST_P(ParameterizedWebFrameTest
, WideDocumentInitializeAtMinimumScale
)
1088 UseMockScrollbarSettings mockScrollbarSettings
;
1090 registerMockedHttpURLLoad("wide_document.html");
1092 FixedLayoutTestWebViewClient client
;
1093 client
.m_screenInfo
.deviceScaleFactor
= 1;
1094 int viewportWidth
= 640;
1095 int viewportHeight
= 480;
1097 // Make sure we initialize to minimum scale, even if the window size
1098 // only becomes available after the load begins.
1099 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1100 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1101 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
1102 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "wide_document.html");
1103 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1105 int wideDocumentWidth
= 1500;
1106 float minimumPageScaleFactor
= viewportWidth
/ (float) wideDocumentWidth
;
1107 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
1108 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
1110 // Assume the user has pinch zoomed to page scale factor 2.
1111 float userPinchPageScaleFactor
= 2;
1112 webViewHelper
.webView()->setPageScaleFactor(userPinchPageScaleFactor
);
1113 webViewHelper
.webView()->layout();
1115 // Make sure we don't reset to initial scale if the page continues to load.
1116 webViewHelper
.webViewImpl()->didCommitLoad(false, false);
1117 webViewHelper
.webViewImpl()->didChangeContentsSize();
1118 EXPECT_EQ(userPinchPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1120 // Make sure we don't reset to initial scale if the viewport size changes.
1121 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
+ 100));
1122 EXPECT_EQ(userPinchPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1125 TEST_P(ParameterizedWebFrameTest
, DelayedViewportInitialScale
)
1127 UseMockScrollbarSettings mockScrollbarSettings
;
1128 registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
1130 FixedLayoutTestWebViewClient client
;
1131 client
.m_screenInfo
.deviceScaleFactor
= 1;
1132 int viewportWidth
= 640;
1133 int viewportHeight
= 480;
1135 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1136 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-auto-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1137 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1139 EXPECT_EQ(0.25f
, webViewHelper
.webView()->pageScaleFactor());
1141 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
1142 ViewportDescription description
= document
->viewportDescription();
1143 description
.zoom
= 2;
1144 document
->setViewportDescription(description
);
1145 webViewHelper
.webView()->layout();
1146 EXPECT_EQ(2, webViewHelper
.webView()->pageScaleFactor());
1149 TEST_P(ParameterizedWebFrameTest
, setLoadWithOverviewModeToFalse
)
1151 UseMockScrollbarSettings mockScrollbarSettings
;
1152 registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
1154 FixedLayoutTestWebViewClient client
;
1155 client
.m_screenInfo
.deviceScaleFactor
= 1;
1156 int viewportWidth
= 640;
1157 int viewportHeight
= 480;
1159 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1160 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-auto-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1161 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1162 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1163 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1165 // The page must be displayed at 100% zoom.
1166 EXPECT_EQ(1.0f
, webViewHelper
.webView()->pageScaleFactor());
1169 TEST_P(ParameterizedWebFrameTest
, SetLoadWithOverviewModeToFalseAndNoWideViewport
)
1171 UseMockScrollbarSettings mockScrollbarSettings
;
1172 registerMockedHttpURLLoad("large-div.html");
1174 FixedLayoutTestWebViewClient client
;
1175 client
.m_screenInfo
.deviceScaleFactor
= 1;
1176 int viewportWidth
= 640;
1177 int viewportHeight
= 480;
1179 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1180 webViewHelper
.initializeAndLoad(m_baseURL
+ "large-div.html", true, 0, &client
, enableViewportSettings
);
1181 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1182 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1183 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1184 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1186 // The page must be displayed at 100% zoom, despite that it hosts a wide div element.
1187 EXPECT_EQ(1.0f
, webViewHelper
.webView()->pageScaleFactor());
1190 TEST_P(ParameterizedWebFrameTest
, NoWideViewportIgnoresPageViewportWidth
)
1192 UseMockScrollbarSettings mockScrollbarSettings
;
1193 registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
1195 FixedLayoutTestWebViewClient client
;
1196 client
.m_screenInfo
.deviceScaleFactor
= 1;
1197 int viewportWidth
= 640;
1198 int viewportHeight
= 480;
1200 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1201 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-auto-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1202 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1203 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1204 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1206 // The page sets viewport width to 3000, but with UseWideViewport == false is must be ignored.
1207 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1208 EXPECT_EQ(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
1211 TEST_P(ParameterizedWebFrameTest
, NoWideViewportIgnoresPageViewportWidthButAccountsScale
)
1213 UseMockScrollbarSettings mockScrollbarSettings
;
1214 registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
1216 FixedLayoutTestWebViewClient client
;
1217 client
.m_screenInfo
.deviceScaleFactor
= 1;
1218 int viewportWidth
= 640;
1219 int viewportHeight
= 480;
1221 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1222 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-wide-2x-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1223 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1224 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1225 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1227 // The page sets viewport width to 3000, but with UseWideViewport == false it must be ignored.
1228 // While the initial scale specified by the page must be accounted.
1229 EXPECT_EQ(viewportWidth
/ 2, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1230 EXPECT_EQ(viewportHeight
/ 2, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
1233 TEST_P(ParameterizedWebFrameTest
, WideViewportSetsTo980WithoutViewportTag
)
1235 UseMockScrollbarSettings mockScrollbarSettings
;
1236 registerMockedHttpURLLoad("no_viewport_tag.html");
1238 FixedLayoutTestWebViewClient client
;
1239 client
.m_screenInfo
.deviceScaleFactor
= 1;
1240 int viewportWidth
= 640;
1241 int viewportHeight
= 480;
1243 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1244 webViewHelper
.initializeAndLoad(m_baseURL
+ "no_viewport_tag.html", true, 0, &client
, enableViewportSettings
);
1245 applyViewportStyleOverride(&webViewHelper
);
1246 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1247 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1248 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1250 EXPECT_EQ(980, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1251 EXPECT_EQ(980.0 / viewportWidth
* viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
1254 TEST_P(ParameterizedWebFrameTest
, WideViewportSetsTo980WithXhtmlMp
)
1256 UseMockScrollbarSettings mockScrollbarSettings
;
1257 registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp.html");
1259 FixedLayoutTestWebViewClient client
;
1260 client
.m_screenInfo
.deviceScaleFactor
= 1;
1261 int viewportWidth
= 640;
1262 int viewportHeight
= 480;
1264 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1265 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1266 applyViewportStyleOverride(&webViewHelper
);
1267 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1268 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1269 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "viewport/viewport-legacy-xhtmlmp.html");
1271 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1272 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1273 EXPECT_EQ(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
1276 TEST_P(ParameterizedWebFrameTest
, NoWideViewportAndHeightInMeta
)
1278 UseMockScrollbarSettings mockScrollbarSettings
;
1279 registerMockedHttpURLLoad("viewport-height-1000.html");
1281 FixedLayoutTestWebViewClient client
;
1282 client
.m_screenInfo
.deviceScaleFactor
= 1;
1283 int viewportWidth
= 640;
1284 int viewportHeight
= 480;
1286 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1287 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-height-1000.html", true, 0, &client
, enableViewportSettings
);
1288 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1289 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1290 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1292 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1295 TEST_P(ParameterizedWebFrameTest
, WideViewportSetsTo980WithAutoWidth
)
1297 UseMockScrollbarSettings mockScrollbarSettings
;
1298 registerMockedHttpURLLoad("viewport-2x-initial-scale.html");
1300 FixedLayoutTestWebViewClient client
;
1301 client
.m_screenInfo
.deviceScaleFactor
= 1;
1302 int viewportWidth
= 640;
1303 int viewportHeight
= 480;
1305 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1306 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-2x-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1307 applyViewportStyleOverride(&webViewHelper
);
1308 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1309 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1310 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1312 EXPECT_EQ(980, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1313 EXPECT_EQ(980.0 / viewportWidth
* viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().height());
1316 TEST_P(ParameterizedWebFrameTest
, PageViewportInitialScaleOverridesLoadWithOverviewMode
)
1318 UseMockScrollbarSettings mockScrollbarSettings
;
1319 registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
1321 FixedLayoutTestWebViewClient client
;
1322 client
.m_screenInfo
.deviceScaleFactor
= 1;
1323 int viewportWidth
= 640;
1324 int viewportHeight
= 480;
1326 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1327 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-wide-2x-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1328 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1329 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1331 // The page must be displayed at 200% zoom, as specified in its viewport meta tag.
1332 EXPECT_EQ(2.0f
, webViewHelper
.webView()->pageScaleFactor());
1335 TEST_P(ParameterizedWebFrameTest
, setInitialPageScaleFactorPermanently
)
1337 UseMockScrollbarSettings mockScrollbarSettings
;
1339 registerMockedHttpURLLoad("fixed_layout.html");
1341 FixedLayoutTestWebViewClient client
;
1342 client
.m_screenInfo
.deviceScaleFactor
= 1;
1343 float enforcedPageScaleFactor
= 2.0f
;
1345 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1346 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
1347 applyViewportStyleOverride(&webViewHelper
);
1348 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1349 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1350 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
1351 webViewHelper
.webView()->layout();
1353 EXPECT_EQ(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1355 int viewportWidth
= 640;
1356 int viewportHeight
= 480;
1357 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1358 webViewHelper
.webView()->layout();
1360 EXPECT_EQ(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1362 webViewHelper
.webView()->setInitialPageScaleOverride(-1);
1363 webViewHelper
.webView()->layout();
1364 EXPECT_EQ(1.0, webViewHelper
.webView()->pageScaleFactor());
1367 TEST_P(ParameterizedWebFrameTest
, PermanentInitialPageScaleFactorOverridesLoadWithOverviewMode
)
1369 UseMockScrollbarSettings mockScrollbarSettings
;
1370 registerMockedHttpURLLoad("viewport-auto-initial-scale.html");
1372 FixedLayoutTestWebViewClient client
;
1373 client
.m_screenInfo
.deviceScaleFactor
= 1;
1374 int viewportWidth
= 640;
1375 int viewportHeight
= 480;
1376 float enforcedPageScaleFactor
= 0.5f
;
1378 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1379 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-auto-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1380 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1381 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
1382 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1384 EXPECT_EQ(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1387 TEST_P(ParameterizedWebFrameTest
, PermanentInitialPageScaleFactorOverridesPageViewportInitialScale
)
1389 UseMockScrollbarSettings mockScrollbarSettings
;
1390 registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");
1392 FixedLayoutTestWebViewClient client
;
1393 client
.m_screenInfo
.deviceScaleFactor
= 1;
1394 int viewportWidth
= 640;
1395 int viewportHeight
= 480;
1396 float enforcedPageScaleFactor
= 0.5f
;
1398 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1399 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-wide-2x-initial-scale.html", true, 0, &client
, enableViewportSettings
);
1400 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
1401 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1403 EXPECT_EQ(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1406 TEST_P(ParameterizedWebFrameTest
, SmallPermanentInitialPageScaleFactorIsClobbered
)
1408 UseMockScrollbarSettings mockScrollbarSettings
;
1409 const char* pages
[] = {
1410 // These pages trigger the clobbering condition. There must be a matching item in "pageScaleFactors" array.
1411 "viewport-device-0.5x-initial-scale.html",
1412 "viewport-initial-scale-1.html",
1413 // These ones do not.
1414 "viewport-auto-initial-scale.html",
1415 "viewport-target-densitydpi-device-and-fixed-width.html"
1417 float pageScaleFactors
[] = { 0.5f
, 1.0f
};
1418 for (size_t i
= 0; i
< ARRAY_SIZE(pages
); ++i
)
1419 registerMockedHttpURLLoad(pages
[i
]);
1421 FixedLayoutTestWebViewClient client
;
1422 client
.m_screenInfo
.deviceScaleFactor
= 1;
1423 int viewportWidth
= 400;
1424 int viewportHeight
= 300;
1425 float enforcedPageScaleFactor
= 0.75f
;
1427 for (size_t i
= 0; i
< ARRAY_SIZE(pages
); ++i
) {
1428 for (int quirkEnabled
= 0; quirkEnabled
<= 1; ++quirkEnabled
) {
1429 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1430 webViewHelper
.initializeAndLoad(m_baseURL
+ pages
[i
], true, 0, &client
, enableViewportSettings
);
1431 applyViewportStyleOverride(&webViewHelper
);
1432 webViewHelper
.webView()->settings()->setClobberUserAgentInitialScaleQuirk(quirkEnabled
);
1433 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
1434 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1436 float expectedPageScaleFactor
= quirkEnabled
&& i
< ARRAY_SIZE(pageScaleFactors
) ? pageScaleFactors
[i
] : enforcedPageScaleFactor
;
1437 EXPECT_EQ(expectedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1442 TEST_P(ParameterizedWebFrameTest
, PermanentInitialPageScaleFactorAffectsLayoutWidth
)
1444 UseMockScrollbarSettings mockScrollbarSettings
;
1446 FixedLayoutTestWebViewClient client
;
1447 client
.m_screenInfo
.deviceScaleFactor
= 1;
1448 int viewportWidth
= 640;
1449 int viewportHeight
= 480;
1450 float enforcedPageScaleFactor
= 0.5;
1452 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1453 webViewHelper
.initializeAndLoad("about:blank", true, 0, &client
, enableViewportSettings
);
1454 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1455 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1456 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(false);
1457 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
1458 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1460 EXPECT_EQ(viewportWidth
/ enforcedPageScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
1461 EXPECT_EQ(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1464 TEST_P(ParameterizedWebFrameTest
, DocumentElementClientHeightWorksWithWrapContentMode
)
1466 UseMockScrollbarSettings mockScrollbarSettings
;
1467 registerMockedHttpURLLoad("0-by-0.html");
1469 FixedLayoutTestWebViewClient client
;
1470 client
.m_screenInfo
.deviceScaleFactor
= 1;
1471 int viewportWidth
= 640;
1472 int viewportHeight
= 480;
1474 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1476 webViewHelper
.initializeAndLoad(m_baseURL
+ "0-by-0.html", true, 0, &client
, configureAndroid
);
1477 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1478 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1480 LocalFrame
* frame
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame();
1481 Document
* document
= frame
->document();
1482 EXPECT_EQ(viewportHeight
, document
->documentElement()->clientHeight());
1483 EXPECT_EQ(viewportWidth
, document
->documentElement()->clientWidth());
1486 TEST_P(ParameterizedWebFrameTest
, SetForceZeroLayoutHeightWorksWithWrapContentMode
)
1488 UseMockScrollbarSettings mockScrollbarSettings
;
1489 registerMockedHttpURLLoad("0-by-0.html");
1491 FixedLayoutTestWebViewClient client
;
1492 client
.m_screenInfo
.deviceScaleFactor
= 1;
1493 int viewportWidth
= 640;
1494 int viewportHeight
= 480;
1496 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1498 webViewHelper
.initializeAndLoad(m_baseURL
+ "0-by-0.html", true, 0, &client
, configureAndroid
);
1499 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1500 DeprecatedPaintLayerCompositor
* compositor
= webViewHelper
.webViewImpl()->compositor();
1501 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1502 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1503 EXPECT_EQ(0.0, compositor
->containerLayer()->size().width());
1504 EXPECT_EQ(0.0, compositor
->containerLayer()->size().height());
1506 webViewHelper
.webView()->resize(WebSize(viewportWidth
, 0));
1507 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1508 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1509 EXPECT_EQ(viewportWidth
, compositor
->containerLayer()->size().width());
1510 EXPECT_EQ(0.0, compositor
->containerLayer()->size().height());
1512 // The flag ForceZeroLayoutHeight will cause the following resize of viewport
1513 // height to be ignored by the outer viewport (the container layer of
1514 // LayerCompositor). The height of the visualViewport, however, is not affected.
1515 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1516 EXPECT_FALSE(webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
1517 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1518 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1519 EXPECT_EQ(viewportWidth
, compositor
->containerLayer()->size().width());
1520 EXPECT_EQ(viewportHeight
, compositor
->containerLayer()->size().height());
1522 LocalFrame
* frame
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame();
1523 VisualViewport
& visualViewport
= frame
->page()->frameHost().visualViewport();
1524 EXPECT_EQ(viewportHeight
, visualViewport
.containerLayer()->size().height());
1525 EXPECT_TRUE(visualViewport
.containerLayer()->platformLayer()->masksToBounds());
1526 EXPECT_FALSE(compositor
->containerLayer()->platformLayer()->masksToBounds());
1529 TEST_P(ParameterizedWebFrameTest
, SetForceZeroLayoutHeight
)
1531 UseMockScrollbarSettings mockScrollbarSettings
;
1532 registerMockedHttpURLLoad("200-by-300.html");
1534 FixedLayoutTestWebViewClient client
;
1535 client
.m_screenInfo
.deviceScaleFactor
= 1;
1536 int viewportWidth
= 640;
1537 int viewportHeight
= 480;
1539 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1541 webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html", true, 0, &client
, enableViewportSettings
);
1542 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1543 webViewHelper
.webView()->layout();
1545 EXPECT_LE(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1546 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1547 EXPECT_TRUE(webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
1549 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1551 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
* 2));
1552 EXPECT_FALSE(webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
1553 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1555 webViewHelper
.webView()->resize(WebSize(viewportWidth
* 2, viewportHeight
));
1556 webViewHelper
.webView()->layout();
1557 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1559 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(false);
1560 EXPECT_LE(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1563 TEST_F(WebFrameTest
, SetForceZeroLayoutHeightWorksWithRelayoutsWhenHeightChanged
)
1565 // this unit test is an attempt to target a real world case where an app could
1566 // 1. call resize(width, 0) and setForceZeroLayoutHeight(true)
1567 // 2. load content (hoping that the viewport height would increase
1568 // as more content is added)
1569 // 3. fail to register touch events aimed at the loaded content
1570 // because the layout is only updated if either width or height is changed
1571 UseMockScrollbarSettings mockScrollbarSettings
;
1572 registerMockedHttpURLLoad("button.html");
1574 FixedLayoutTestWebViewClient client
;
1575 client
.m_screenInfo
.deviceScaleFactor
= 1;
1576 int viewportWidth
= 640;
1577 int viewportHeight
= 480;
1579 FrameTestHelpers::WebViewHelper webViewHelper
;
1581 webViewHelper
.initializeAndLoad(m_baseURL
+ "button.html", true, 0, &client
, configureAndroid
);
1582 // set view height to zero so that if the height of the view is not
1583 // successfully updated during later resizes touch events will fail
1584 // (as in not hit content included in the view)
1585 webViewHelper
.webView()->resize(WebSize(viewportWidth
, 0));
1586 webViewHelper
.webView()->layout();
1588 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1589 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1591 IntPoint hitPoint
= IntPoint(30, 30); // button size is 100x100
1593 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
1594 Document
* document
= frame
->frame()->document();
1595 Element
* element
= document
->getElementById("tap_button");
1597 ASSERT_NE(nullptr, element
);
1598 EXPECT_EQ(String("oldValue"), element
->innerText());
1600 PlatformGestureEvent
gestureEvent(PlatformEvent::Type::GestureTap
, hitPoint
, hitPoint
, IntSize(0, 0), 0, false, false, false, false);
1601 webViewHelper
.webViewImpl()->mainFrameImpl()->frame()->eventHandler().handleGestureEvent(gestureEvent
);
1602 // when pressed, the button changes its own text to "updatedValue"
1603 EXPECT_EQ(String("updatedValue"), element
->innerText());
1606 TEST_P(ParameterizedWebFrameTest
, SetForceZeroLayoutHeightWorksAcrossNavigations
)
1608 UseMockScrollbarSettings mockScrollbarSettings
;
1609 registerMockedHttpURLLoad("200-by-300.html");
1610 registerMockedHttpURLLoad("large-div.html");
1612 FixedLayoutTestWebViewClient client
;
1613 client
.m_screenInfo
.deviceScaleFactor
= 1;
1614 int viewportWidth
= 640;
1615 int viewportHeight
= 480;
1617 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1619 webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html", true, 0, &client
, enableViewportSettings
);
1620 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1621 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1622 webViewHelper
.webView()->layout();
1624 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "large-div.html");
1625 webViewHelper
.webView()->layout();
1627 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1630 TEST_P(ParameterizedWebFrameTest
, SetForceZeroLayoutHeightWithWideViewportQuirk
)
1632 UseMockScrollbarSettings mockScrollbarSettings
;
1633 registerMockedHttpURLLoad("200-by-300.html");
1635 FixedLayoutTestWebViewClient client
;
1636 client
.m_screenInfo
.deviceScaleFactor
= 1;
1637 int viewportWidth
= 640;
1638 int viewportHeight
= 480;
1640 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1642 webViewHelper
.initializeAndLoad(m_baseURL
+ "200-by-300.html", true, 0, &client
, enableViewportSettings
);
1643 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1644 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1645 webViewHelper
.webView()->settings()->setForceZeroLayoutHeight(true);
1646 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1647 webViewHelper
.webView()->layout();
1649 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1652 TEST_P(ParameterizedWebFrameTest
, WideViewportAndWideContentWithInitialScale
)
1654 UseMockScrollbarSettings mockScrollbarSettings
;
1655 registerMockedHttpURLLoad("wide_document_width_viewport.html");
1657 FixedLayoutTestWebViewClient client
;
1658 client
.m_screenInfo
.deviceScaleFactor
= 1;
1659 int viewportWidth
= 600;
1660 int viewportHeight
= 800;
1662 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1663 webViewHelper
.initializeAndLoad("about:blank", true, 0, &client
, enableViewportSettings
);
1664 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1665 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1666 webViewHelper
.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
1667 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1669 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "wide_document_width_viewport.html");
1670 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1672 int wideDocumentWidth
= 800;
1673 float minimumPageScaleFactor
= viewportWidth
/ (float) wideDocumentWidth
;
1674 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
1675 EXPECT_EQ(minimumPageScaleFactor
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
1678 TEST_P(ParameterizedWebFrameTest
, WideViewportQuirkClobbersHeight
)
1680 UseMockScrollbarSettings mockScrollbarSettings
;
1681 registerMockedHttpURLLoad("viewport-height-1000.html");
1683 FixedLayoutTestWebViewClient client
;
1684 client
.m_screenInfo
.deviceScaleFactor
= 1;
1685 int viewportWidth
= 600;
1686 int viewportHeight
= 800;
1688 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1689 webViewHelper
.initializeAndLoad("about:blank", true, 0, &client
, enableViewportSettings
);
1690 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1691 webViewHelper
.webView()->settings()->setUseWideViewport(false);
1692 webViewHelper
.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
1693 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1695 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "viewport-height-1000.html");
1696 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1698 EXPECT_EQ(800, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1699 EXPECT_EQ(1, webViewHelper
.webView()->pageScaleFactor());
1702 TEST_P(ParameterizedWebFrameTest
, LayoutSize320Quirk
)
1704 UseMockScrollbarSettings mockScrollbarSettings
;
1705 registerMockedHttpURLLoad("viewport/viewport-30.html");
1707 FixedLayoutTestWebViewClient client
;
1708 client
.m_screenInfo
.deviceScaleFactor
= 1;
1709 int viewportWidth
= 600;
1710 int viewportHeight
= 800;
1712 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1713 webViewHelper
.initializeAndLoad("about:blank", true, 0, &client
, enableViewportSettings
);
1714 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1715 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1716 webViewHelper
.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
1717 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1719 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "viewport/viewport-30.html");
1720 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1722 EXPECT_EQ(600, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1723 EXPECT_EQ(800, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1724 EXPECT_EQ(1, webViewHelper
.webView()->pageScaleFactor());
1726 // The magic number to snap to device-width is 320, so test that 321 is
1728 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
1729 ViewportDescription description
= document
->viewportDescription();
1730 description
.minWidth
= Length(321, blink::Fixed
);
1731 description
.maxWidth
= Length(321, blink::Fixed
);
1732 document
->setViewportDescription(description
);
1733 webViewHelper
.webView()->layout();
1734 EXPECT_EQ(321, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1736 description
.minWidth
= Length(320, blink::Fixed
);
1737 description
.maxWidth
= Length(320, blink::Fixed
);
1738 document
->setViewportDescription(description
);
1739 webViewHelper
.webView()->layout();
1740 EXPECT_EQ(600, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1742 description
= document
->viewportDescription();
1743 description
.maxHeight
= Length(1000, blink::Fixed
);
1744 document
->setViewportDescription(description
);
1745 webViewHelper
.webView()->layout();
1746 EXPECT_EQ(1000, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1748 description
.maxHeight
= Length(320, blink::Fixed
);
1749 document
->setViewportDescription(description
);
1750 webViewHelper
.webView()->layout();
1751 EXPECT_EQ(800, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height());
1754 TEST_P(ParameterizedWebFrameTest
, ZeroValuesQuirk
)
1756 UseMockScrollbarSettings mockScrollbarSettings
;
1757 registerMockedHttpURLLoad("viewport-zero-values.html");
1759 FixedLayoutTestWebViewClient client
;
1760 client
.m_screenInfo
.deviceScaleFactor
= 1;
1761 int viewportWidth
= 640;
1762 int viewportHeight
= 480;
1764 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1765 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1766 webViewHelper
.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
1767 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1768 webViewHelper
.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
1769 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "viewport-zero-values.html");
1770 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1772 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1773 EXPECT_EQ(1.0f
, webViewHelper
.webView()->pageScaleFactor());
1775 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1776 webViewHelper
.webView()->layout();
1777 EXPECT_EQ(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1778 EXPECT_EQ(1.0f
, webViewHelper
.webView()->pageScaleFactor());
1781 TEST_P(ParameterizedWebFrameTest
, OverflowHiddenDisablesScrolling
)
1783 registerMockedHttpURLLoad("body-overflow-hidden.html");
1785 FixedLayoutTestWebViewClient client
;
1786 client
.m_screenInfo
.deviceScaleFactor
= 1;
1787 int viewportWidth
= 640;
1788 int viewportHeight
= 480;
1790 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1791 webViewHelper
.initialize(true, 0, &client
);
1792 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "body-overflow-hidden.html");
1793 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1795 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
1796 EXPECT_FALSE(view
->userInputScrollable(VerticalScrollbar
));
1797 EXPECT_FALSE(view
->userInputScrollable(HorizontalScrollbar
));
1800 TEST_P(ParameterizedWebFrameTest
, OverflowHiddenDisablesScrollingWithSetCanHaveScrollbars
)
1802 registerMockedHttpURLLoad("body-overflow-hidden-short.html");
1804 FixedLayoutTestWebViewClient client
;
1805 client
.m_screenInfo
.deviceScaleFactor
= 1;
1806 int viewportWidth
= 640;
1807 int viewportHeight
= 480;
1809 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1810 webViewHelper
.initialize(true, 0, &client
);
1811 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "body-overflow-hidden-short.html");
1812 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1814 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
1815 EXPECT_FALSE(view
->userInputScrollable(VerticalScrollbar
));
1816 EXPECT_FALSE(view
->userInputScrollable(HorizontalScrollbar
));
1818 webViewHelper
.webViewImpl()->mainFrameImpl()->setCanHaveScrollbars(true);
1819 EXPECT_FALSE(view
->userInputScrollable(VerticalScrollbar
));
1820 EXPECT_FALSE(view
->userInputScrollable(HorizontalScrollbar
));
1823 TEST_F(WebFrameTest
, IgnoreOverflowHiddenQuirk
)
1825 registerMockedHttpURLLoad("body-overflow-hidden.html");
1827 FixedLayoutTestWebViewClient client
;
1828 client
.m_screenInfo
.deviceScaleFactor
= 1;
1829 int viewportWidth
= 640;
1830 int viewportHeight
= 480;
1832 FrameTestHelpers::WebViewHelper webViewHelper
;
1833 webViewHelper
.initialize(true, 0, &client
);
1834 webViewHelper
.webView()->settings()->setIgnoreMainFrameOverflowHiddenQuirk(true);
1835 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "body-overflow-hidden.html");
1836 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1838 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
1839 EXPECT_TRUE(view
->userInputScrollable(VerticalScrollbar
));
1842 TEST_P(ParameterizedWebFrameTest
, NonZeroValuesNoQuirk
)
1844 UseMockScrollbarSettings mockScrollbarSettings
;
1845 registerMockedHttpURLLoad("viewport-nonzero-values.html");
1847 FixedLayoutTestWebViewClient client
;
1848 client
.m_screenInfo
.deviceScaleFactor
= 1;
1849 int viewportWidth
= 640;
1850 int viewportHeight
= 480;
1851 float expectedPageScaleFactor
= 0.5f
;
1853 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1854 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1855 webViewHelper
.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
1856 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
1857 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "viewport-nonzero-values.html");
1858 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1860 EXPECT_EQ(viewportWidth
/ expectedPageScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1861 EXPECT_EQ(expectedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1863 webViewHelper
.webView()->settings()->setUseWideViewport(true);
1864 webViewHelper
.webView()->layout();
1865 EXPECT_EQ(viewportWidth
/ expectedPageScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width());
1866 EXPECT_EQ(expectedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor());
1869 TEST_P(ParameterizedWebFrameTest
, setPageScaleFactorDoesNotLayout
)
1871 UseMockScrollbarSettings mockScrollbarSettings
;
1872 registerMockedHttpURLLoad("fixed_layout.html");
1874 FixedLayoutTestWebViewClient client
;
1875 client
.m_screenInfo
.deviceScaleFactor
= 1;
1876 // Small viewport to ensure there are always scrollbars.
1877 int viewportWidth
= 64;
1878 int viewportHeight
= 48;
1880 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1881 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
1882 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1883 webViewHelper
.webView()->layout();
1885 int prevLayoutCount
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
1886 webViewHelper
.webViewImpl()->setPageScaleFactor(3);
1887 EXPECT_FALSE(webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
1888 EXPECT_EQ(prevLayoutCount
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
1891 TEST_P(ParameterizedWebFrameTest
, setPageScaleFactorWithOverlayScrollbarsDoesNotLayout
)
1893 UseMockScrollbarSettings mockScrollbarSettings
;
1895 registerMockedHttpURLLoad("fixed_layout.html");
1897 FixedLayoutTestWebViewClient client
;
1898 client
.m_screenInfo
.deviceScaleFactor
= 1;
1899 int viewportWidth
= 640;
1900 int viewportHeight
= 480;
1902 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1903 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
1904 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1905 webViewHelper
.webView()->layout();
1907 int prevLayoutCount
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutCount();
1908 webViewHelper
.webViewImpl()->setPageScaleFactor(30);
1909 EXPECT_FALSE(webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->needsLayout());
1910 EXPECT_EQ(prevLayoutCount
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutCount());
1914 TEST_P(ParameterizedWebFrameTest
, pageScaleFactorWrittenToHistoryItem
)
1916 UseMockScrollbarSettings mockScrollbarSettings
;
1917 registerMockedHttpURLLoad("fixed_layout.html");
1919 FixedLayoutTestWebViewClient client
;
1920 client
.m_screenInfo
.deviceScaleFactor
= 1;
1921 int viewportWidth
= 640;
1922 int viewportHeight
= 480;
1924 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1925 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
1926 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1927 webViewHelper
.webView()->layout();
1929 webViewHelper
.webView()->setPageScaleFactor(3);
1930 EXPECT_EQ(3, toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->loader().currentItem()->pageScaleFactor());
1933 TEST_P(ParameterizedWebFrameTest
, initialScaleWrittenToHistoryItem
)
1935 UseMockScrollbarSettings mockScrollbarSettings
;
1936 registerMockedHttpURLLoad("fixed_layout.html");
1938 FixedLayoutTestWebViewClient client
;
1939 client
.m_screenInfo
.deviceScaleFactor
= 1;
1940 int viewportWidth
= 640;
1941 int viewportHeight
= 480;
1943 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1944 webViewHelper
.initialize(true, 0, &client
, enableViewportSettings
);
1945 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
1946 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "fixed_layout.html");
1947 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1948 webViewHelper
.webView()->layout();
1950 int defaultFixedLayoutWidth
= 980;
1951 float minimumPageScaleFactor
= viewportWidth
/ (float) defaultFixedLayoutWidth
;
1952 EXPECT_EQ(minimumPageScaleFactor
, toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->loader().currentItem()->pageScaleFactor());
1955 TEST_P(ParameterizedWebFrameTest
, pageScaleFactorDoesntShrinkFrameView
)
1957 UseMockScrollbarSettings mockScrollbarSettings
;
1958 registerMockedHttpURLLoad("large-div.html");
1960 FixedLayoutTestWebViewClient client
;
1961 client
.m_screenInfo
.deviceScaleFactor
= 1;
1962 // Small viewport to ensure there are always scrollbars.
1963 int viewportWidth
= 64;
1964 int viewportHeight
= 48;
1966 FrameTestHelpers::WebViewHelper
webViewHelper(this);
1967 webViewHelper
.initializeAndLoad(m_baseURL
+ "large-div.html", true, 0, &client
, enableViewportSettings
);
1968 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
1969 webViewHelper
.webView()->layout();
1971 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
1972 int viewportWidthMinusScrollbar
= viewportWidth
;
1973 int viewportHeightMinusScrollbar
= viewportHeight
;
1975 if (view
->verticalScrollbar() && !view
->verticalScrollbar()->isOverlayScrollbar())
1976 viewportWidthMinusScrollbar
-= 15;
1978 if (view
->horizontalScrollbar() && !view
->horizontalScrollbar()->isOverlayScrollbar())
1979 viewportHeightMinusScrollbar
-= 15;
1981 webViewHelper
.webView()->setPageScaleFactor(2);
1983 IntSize unscaledSize
= view
->visibleContentSize(IncludeScrollbars
);
1984 EXPECT_EQ(viewportWidth
, unscaledSize
.width());
1985 EXPECT_EQ(viewportHeight
, unscaledSize
.height());
1987 IntSize unscaledSizeMinusScrollbar
= view
->visibleContentSize(ExcludeScrollbars
);
1988 EXPECT_EQ(viewportWidthMinusScrollbar
, unscaledSizeMinusScrollbar
.width());
1989 EXPECT_EQ(viewportHeightMinusScrollbar
, unscaledSizeMinusScrollbar
.height());
1991 IntSize frameViewSize
= view
->visibleContentRect().size();
1992 EXPECT_EQ(viewportWidthMinusScrollbar
, frameViewSize
.width());
1993 EXPECT_EQ(viewportHeightMinusScrollbar
, frameViewSize
.height());
1996 TEST_P(ParameterizedWebFrameTest
, pageScaleFactorDoesNotApplyCssTransform
)
1998 UseMockScrollbarSettings mockScrollbarSettings
;
1999 registerMockedHttpURLLoad("fixed_layout.html");
2001 FixedLayoutTestWebViewClient client
;
2002 client
.m_screenInfo
.deviceScaleFactor
= 1;
2003 int viewportWidth
= 640;
2004 int viewportHeight
= 480;
2006 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2007 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
2008 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2009 webViewHelper
.webView()->layout();
2011 webViewHelper
.webView()->setPageScaleFactor(2);
2013 EXPECT_EQ(980, toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->contentLayoutObject()->unscaledDocumentRect().width());
2014 EXPECT_EQ(980, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
2017 TEST_P(ParameterizedWebFrameTest
, targetDensityDpiHigh
)
2019 UseMockScrollbarSettings mockScrollbarSettings
;
2020 registerMockedHttpURLLoad("viewport-target-densitydpi-high.html");
2022 FixedLayoutTestWebViewClient client
;
2024 float targetDpi
= 240.0f
;
2025 float deviceScaleFactors
[] = { 1.0f
, 4.0f
/ 3.0f
, 2.0f
};
2026 int viewportWidth
= 640;
2027 int viewportHeight
= 480;
2029 for (size_t i
= 0; i
< ARRAY_SIZE(deviceScaleFactors
); ++i
) {
2030 float deviceScaleFactor
= deviceScaleFactors
[i
];
2031 float deviceDpi
= deviceScaleFactor
* 160.0f
;
2032 client
.m_screenInfo
.deviceScaleFactor
= deviceScaleFactor
;
2034 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2035 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-target-densitydpi-high.html", true, 0, &client
, enableViewportSettings
);
2036 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2037 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2038 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2040 // We need to account for the fact that logical pixels are unconditionally multiplied by deviceScaleFactor to produce
2042 float densityDpiScaleRatio
= deviceScaleFactor
* targetDpi
/ deviceDpi
;
2043 EXPECT_NEAR(viewportWidth
* densityDpiScaleRatio
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2044 EXPECT_NEAR(viewportHeight
* densityDpiScaleRatio
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2045 EXPECT_NEAR(1.0f
/ densityDpiScaleRatio
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2049 TEST_P(ParameterizedWebFrameTest
, targetDensityDpiDevice
)
2051 UseMockScrollbarSettings mockScrollbarSettings
;
2052 registerMockedHttpURLLoad("viewport-target-densitydpi-device.html");
2054 float deviceScaleFactors
[] = { 1.0f
, 4.0f
/ 3.0f
, 2.0f
};
2056 FixedLayoutTestWebViewClient client
;
2057 int viewportWidth
= 640;
2058 int viewportHeight
= 480;
2060 for (size_t i
= 0; i
< ARRAY_SIZE(deviceScaleFactors
); ++i
) {
2061 client
.m_screenInfo
.deviceScaleFactor
= deviceScaleFactors
[i
];
2063 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2064 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-target-densitydpi-device.html", true, 0, &client
, enableViewportSettings
);
2065 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2066 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2067 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2069 EXPECT_NEAR(viewportWidth
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2070 EXPECT_NEAR(viewportHeight
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2071 EXPECT_NEAR(1.0f
/ client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2075 TEST_P(ParameterizedWebFrameTest
, targetDensityDpiDeviceAndFixedWidth
)
2077 UseMockScrollbarSettings mockScrollbarSettings
;
2078 registerMockedHttpURLLoad("viewport-target-densitydpi-device-and-fixed-width.html");
2080 float deviceScaleFactors
[] = { 1.0f
, 4.0f
/ 3.0f
, 2.0f
};
2082 FixedLayoutTestWebViewClient client
;
2083 int viewportWidth
= 640;
2084 int viewportHeight
= 480;
2086 for (size_t i
= 0; i
< ARRAY_SIZE(deviceScaleFactors
); ++i
) {
2087 client
.m_screenInfo
.deviceScaleFactor
= deviceScaleFactors
[i
];
2089 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2090 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-target-densitydpi-device-and-fixed-width.html", true, 0, &client
, enableViewportSettings
);
2091 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2092 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2093 webViewHelper
.webView()->settings()->setUseWideViewport(true);
2094 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2096 EXPECT_NEAR(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2097 EXPECT_NEAR(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2098 EXPECT_NEAR(1.0f
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2102 TEST_P(ParameterizedWebFrameTest
, NoWideViewportAndScaleLessThanOne
)
2104 UseMockScrollbarSettings mockScrollbarSettings
;
2105 registerMockedHttpURLLoad("viewport-initial-scale-less-than-1.html");
2107 FixedLayoutTestWebViewClient client
;
2108 client
.m_screenInfo
.deviceScaleFactor
= 1.33f
;
2109 int viewportWidth
= 640;
2110 int viewportHeight
= 480;
2112 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2113 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-initial-scale-less-than-1.html", true, 0, &client
, enableViewportSettings
);
2114 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2115 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2116 webViewHelper
.webView()->settings()->setUseWideViewport(false);
2117 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2118 webViewHelper
.webView()->layout();
2120 EXPECT_NEAR(viewportWidth
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2121 EXPECT_NEAR(viewportHeight
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2122 EXPECT_NEAR(1.0f
/ client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2125 TEST_P(ParameterizedWebFrameTest
, NoWideViewportAndScaleLessThanOneWithDeviceWidth
)
2127 UseMockScrollbarSettings mockScrollbarSettings
;
2128 registerMockedHttpURLLoad("viewport-initial-scale-less-than-1-device-width.html");
2130 FixedLayoutTestWebViewClient client
;
2131 client
.m_screenInfo
.deviceScaleFactor
= 1.33f
;
2132 int viewportWidth
= 640;
2133 int viewportHeight
= 480;
2135 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2136 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-initial-scale-less-than-1-device-width.html", true, 0, &client
, enableViewportSettings
);
2137 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2138 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2139 webViewHelper
.webView()->settings()->setUseWideViewport(false);
2140 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2141 webViewHelper
.webView()->layout();
2143 const float pageZoom
= 0.25f
;
2144 EXPECT_NEAR(viewportWidth
* client
.m_screenInfo
.deviceScaleFactor
/ pageZoom
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2145 EXPECT_NEAR(viewportHeight
* client
.m_screenInfo
.deviceScaleFactor
/ pageZoom
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2146 EXPECT_NEAR(1.0f
/ client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2149 TEST_P(ParameterizedWebFrameTest
, NoWideViewportAndNoViewportWithInitialPageScaleOverride
)
2151 UseMockScrollbarSettings mockScrollbarSettings
;
2152 registerMockedHttpURLLoad("large-div.html");
2154 FixedLayoutTestWebViewClient client
;
2155 int viewportWidth
= 640;
2156 int viewportHeight
= 480;
2157 float enforcedPageScaleFactor
= 5.0f
;
2159 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2160 webViewHelper
.initializeAndLoad(m_baseURL
+ "large-div.html", true, 0, &client
, enableViewportSettings
);
2161 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
2162 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2163 webViewHelper
.webView()->settings()->setUseWideViewport(false);
2164 webViewHelper
.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor
);
2165 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2166 webViewHelper
.webView()->layout();
2168 EXPECT_NEAR(viewportWidth
/ enforcedPageScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2169 EXPECT_NEAR(viewportHeight
/ enforcedPageScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2170 EXPECT_NEAR(enforcedPageScaleFactor
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2173 TEST_P(ParameterizedWebFrameTest
, NoUserScalableQuirkIgnoresViewportScale
)
2175 UseMockScrollbarSettings mockScrollbarSettings
;
2176 registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
2178 FixedLayoutTestWebViewClient client
;
2179 int viewportWidth
= 640;
2180 int viewportHeight
= 480;
2182 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2183 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client
, enableViewportSettings
);
2184 webViewHelper
.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
2185 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2186 webViewHelper
.webView()->layout();
2188 EXPECT_NEAR(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2189 EXPECT_NEAR(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2190 EXPECT_NEAR(1.0f
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2193 TEST_P(ParameterizedWebFrameTest
, NoUserScalableQuirkIgnoresViewportScaleForNonWideViewport
)
2195 UseMockScrollbarSettings mockScrollbarSettings
;
2196 registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");
2198 FixedLayoutTestWebViewClient client
;
2199 client
.m_screenInfo
.deviceScaleFactor
= 1.33f
;
2200 int viewportWidth
= 640;
2201 int viewportHeight
= 480;
2203 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2204 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-initial-scale-and-user-scalable-no.html", true, 0, &client
, enableViewportSettings
);
2205 webViewHelper
.webView()->settings()->setSupportDeprecatedTargetDensityDPI(true);
2206 webViewHelper
.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
2207 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2208 webViewHelper
.webView()->settings()->setUseWideViewport(false);
2209 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2210 webViewHelper
.webView()->layout();
2212 EXPECT_NEAR(viewportWidth
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2213 EXPECT_NEAR(viewportHeight
* client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2214 EXPECT_NEAR(1.0f
/ client
.m_screenInfo
.deviceScaleFactor
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2217 TEST_P(ParameterizedWebFrameTest
, NoUserScalableQuirkIgnoresViewportScaleForWideViewport
)
2219 UseMockScrollbarSettings mockScrollbarSettings
;
2220 registerMockedHttpURLLoad("viewport-2x-initial-scale-non-user-scalable.html");
2222 FixedLayoutTestWebViewClient client
;
2223 int viewportWidth
= 640;
2224 int viewportHeight
= 480;
2226 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2227 webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-2x-initial-scale-non-user-scalable.html", true, 0, &client
, enableViewportSettings
);
2228 webViewHelper
.webView()->settings()->setViewportMetaNonUserScalableQuirk(true);
2229 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2230 webViewHelper
.webView()->settings()->setUseWideViewport(true);
2231 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2233 EXPECT_NEAR(viewportWidth
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().width(), 1.0f
);
2234 EXPECT_NEAR(viewportHeight
, webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutSize().height(), 1.0f
);
2235 EXPECT_NEAR(1.0f
, webViewHelper
.webView()->pageScaleFactor(), 0.01f
);
2238 TEST_P(ParameterizedWebFrameTest
, DesktopPageCanBeZoomedInWhenWideViewportIsTurnedOff
)
2240 UseMockScrollbarSettings mockScrollbarSettings
;
2241 registerMockedHttpURLLoad("no_viewport_tag.html");
2243 FixedLayoutTestWebViewClient client
;
2244 int viewportWidth
= 640;
2245 int viewportHeight
= 480;
2247 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2248 webViewHelper
.initializeAndLoad(m_baseURL
+ "no_viewport_tag.html", true, 0, &client
, enableViewportSettings
);
2249 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
2250 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
2251 webViewHelper
.webView()->settings()->setUseWideViewport(false);
2252 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2254 EXPECT_NEAR(1.0f
, webViewHelper
.webViewImpl()->pageScaleFactor(), 0.01f
);
2255 EXPECT_NEAR(1.0f
, webViewHelper
.webViewImpl()->minimumPageScaleFactor(), 0.01f
);
2256 EXPECT_NEAR(5.0f
, webViewHelper
.webViewImpl()->maximumPageScaleFactor(), 0.01f
);
2259 class WebFrameResizeTest
: public ParameterizedWebFrameTest
{
2262 static FloatSize
computeRelativeOffset(const IntPoint
& absoluteOffset
, const LayoutRect
& rect
)
2264 FloatSize relativeOffset
= FloatPoint(absoluteOffset
) - FloatPoint(rect
.location());
2265 relativeOffset
.scale(1.f
/ rect
.width(), 1.f
/ rect
.height());
2266 return relativeOffset
;
2269 void testResizeYieldsCorrectScrollAndScale(const char* url
,
2270 const float initialPageScaleFactor
,
2271 const WebSize scrollOffset
,
2272 const WebSize viewportSize
,
2273 const bool shouldScaleRelativeToViewportWidth
) {
2274 UseMockScrollbarSettings mockScrollbarSettings
;
2275 registerMockedHttpURLLoad(url
);
2277 const float aspectRatio
= static_cast<float>(viewportSize
.width
) / viewportSize
.height
;
2279 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2280 webViewHelper
.initializeAndLoad(m_baseURL
+ url
, true, 0, 0, enableViewportSettings
);
2281 webViewHelper
.webViewImpl()->setDefaultPageScaleLimits(0.25f
, 5);
2283 // Origin scrollOffsets preserved under resize.
2285 webViewHelper
.webViewImpl()->resize(WebSize(viewportSize
.width
, viewportSize
.height
));
2286 webViewHelper
.webViewImpl()->setPageScaleFactor(initialPageScaleFactor
);
2287 ASSERT_EQ(viewportSize
, webViewHelper
.webViewImpl()->size());
2288 ASSERT_EQ(initialPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
2289 webViewHelper
.webViewImpl()->resize(WebSize(viewportSize
.height
, viewportSize
.width
));
2290 float expectedPageScaleFactor
= initialPageScaleFactor
* (shouldScaleRelativeToViewportWidth
? 1 / aspectRatio
: 1);
2291 EXPECT_NEAR(expectedPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor(), 0.05f
);
2292 EXPECT_EQ(WebSize(), webViewHelper
.webViewImpl()->mainFrame()->scrollOffset());
2295 // Resizing just the height should not affect pageScaleFactor or scrollOffset.
2297 webViewHelper
.webViewImpl()->resize(WebSize(viewportSize
.width
, viewportSize
.height
));
2298 webViewHelper
.webViewImpl()->setPageScaleFactor(initialPageScaleFactor
);
2299 webViewHelper
.webViewImpl()->mainFrame()->setScrollOffset(scrollOffset
);
2300 webViewHelper
.webViewImpl()->layout();
2301 const WebSize expectedScrollOffset
= webViewHelper
.webViewImpl()->mainFrame()->scrollOffset();
2302 webViewHelper
.webViewImpl()->resize(WebSize(viewportSize
.width
, viewportSize
.height
* 0.8f
));
2303 EXPECT_EQ(initialPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
2304 EXPECT_EQ(expectedScrollOffset
, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset());
2305 webViewHelper
.webViewImpl()->resize(WebSize(viewportSize
.width
, viewportSize
.height
* 0.8f
));
2306 EXPECT_EQ(initialPageScaleFactor
, webViewHelper
.webViewImpl()->pageScaleFactor());
2307 EXPECT_EQ(expectedScrollOffset
, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset());
2312 INSTANTIATE_TEST_CASE_P(All
, WebFrameResizeTest
, ::testing::Values(
2313 ParameterizedWebFrameTestConfig::Default
,
2314 ParameterizedWebFrameTestConfig::RootLayerScrolls
));
2316 TEST_P(WebFrameResizeTest
, ResizeYieldsCorrectScrollAndScaleForWidthEqualsDeviceWidth
)
2318 // With width=device-width, pageScaleFactor is preserved across resizes as
2319 // long as the content adjusts according to the device-width.
2320 const char* url
= "resize_scroll_mobile.html";
2321 const float initialPageScaleFactor
= 1;
2322 const WebSize
scrollOffset(0, 50);
2323 const WebSize
viewportSize(120, 160);
2324 const bool shouldScaleRelativeToViewportWidth
= true;
2326 testResizeYieldsCorrectScrollAndScale(
2327 url
, initialPageScaleFactor
, scrollOffset
, viewportSize
, shouldScaleRelativeToViewportWidth
);
2330 TEST_P(WebFrameResizeTest
, ResizeYieldsCorrectScrollAndScaleForMinimumScale
)
2332 // This tests a scenario where minimum-scale is set to 1.0, but some element
2333 // on the page is slightly larger than the portrait width, so our "natural"
2334 // minimum-scale would be lower. In that case, we should stick to 1.0 scale
2335 // on rotation and not do anything strange.
2336 const char* url
= "resize_scroll_minimum_scale.html";
2337 const float initialPageScaleFactor
= 1;
2338 const WebSize
scrollOffset(0, 0);
2339 const WebSize
viewportSize(240, 320);
2340 const bool shouldScaleRelativeToViewportWidth
= false;
2342 testResizeYieldsCorrectScrollAndScale(
2343 url
, initialPageScaleFactor
, scrollOffset
, viewportSize
, shouldScaleRelativeToViewportWidth
);
2346 TEST_P(WebFrameResizeTest
, ResizeYieldsCorrectScrollAndScaleForFixedWidth
)
2348 // With a fixed width, pageScaleFactor scales by the relative change in viewport width.
2349 const char* url
= "resize_scroll_fixed_width.html";
2350 const float initialPageScaleFactor
= 2;
2351 const WebSize
scrollOffset(0, 200);
2352 const WebSize
viewportSize(240, 320);
2353 const bool shouldScaleRelativeToViewportWidth
= true;
2355 testResizeYieldsCorrectScrollAndScale(
2356 url
, initialPageScaleFactor
, scrollOffset
, viewportSize
, shouldScaleRelativeToViewportWidth
);
2359 TEST_P(WebFrameResizeTest
, ResizeYieldsCorrectScrollAndScaleForFixedLayout
)
2361 // With a fixed layout, pageScaleFactor scales by the relative change in viewport width.
2362 const char* url
= "resize_scroll_fixed_layout.html";
2363 const float initialPageScaleFactor
= 2;
2364 const WebSize
scrollOffset(200, 400);
2365 const WebSize
viewportSize(320, 240);
2366 const bool shouldScaleRelativeToViewportWidth
= true;
2368 testResizeYieldsCorrectScrollAndScale(
2369 url
, initialPageScaleFactor
, scrollOffset
, viewportSize
, shouldScaleRelativeToViewportWidth
);
2372 TEST_P(ParameterizedWebFrameTest
, pageScaleFactorUpdatesScrollbars
)
2374 UseMockScrollbarSettings mockScrollbarSettings
;
2375 registerMockedHttpURLLoad("fixed_layout.html");
2377 FixedLayoutTestWebViewClient client
;
2378 client
.m_screenInfo
.deviceScaleFactor
= 1;
2379 int viewportWidth
= 640;
2380 int viewportHeight
= 480;
2382 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2383 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed_layout.html", true, 0, &client
, enableViewportSettings
);
2384 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2385 webViewHelper
.webView()->layout();
2387 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
2388 EXPECT_EQ(view
->scrollSize(HorizontalScrollbar
), view
->contentsSize().width() - view
->visibleContentRect().width());
2389 EXPECT_EQ(view
->scrollSize(VerticalScrollbar
), view
->contentsSize().height() - view
->visibleContentRect().height());
2391 webViewHelper
.webView()->setPageScaleFactor(10);
2393 EXPECT_EQ(view
->scrollSize(HorizontalScrollbar
), view
->contentsSize().width() - view
->visibleContentRect().width());
2394 EXPECT_EQ(view
->scrollSize(VerticalScrollbar
), view
->contentsSize().height() - view
->visibleContentRect().height());
2397 TEST_P(ParameterizedWebFrameTest
, CanOverrideScaleLimits
)
2399 UseMockScrollbarSettings mockScrollbarSettings
;
2401 registerMockedHttpURLLoad("no_scale_for_you.html");
2403 FixedLayoutTestWebViewClient client
;
2404 client
.m_screenInfo
.deviceScaleFactor
= 1;
2405 int viewportWidth
= 640;
2406 int viewportHeight
= 480;
2408 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2409 webViewHelper
.initializeAndLoad(m_baseURL
+ "no_scale_for_you.html", true, 0, &client
, enableViewportSettings
);
2410 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 5);
2411 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2413 EXPECT_EQ(2.0f
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
2414 EXPECT_EQ(2.0f
, webViewHelper
.webViewImpl()->maximumPageScaleFactor());
2416 webViewHelper
.webView()->setIgnoreViewportTagScaleLimits(true);
2417 webViewHelper
.webView()->layout();
2419 EXPECT_EQ(1.0f
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
2420 EXPECT_EQ(5.0f
, webViewHelper
.webViewImpl()->maximumPageScaleFactor());
2422 webViewHelper
.webView()->setIgnoreViewportTagScaleLimits(false);
2423 webViewHelper
.webView()->layout();
2425 EXPECT_EQ(2.0f
, webViewHelper
.webViewImpl()->minimumPageScaleFactor());
2426 EXPECT_EQ(2.0f
, webViewHelper
.webViewImpl()->maximumPageScaleFactor());
2429 // Android doesn't have scrollbars on the main FrameView
2431 TEST_F(WebFrameTest
, DISABLED_updateOverlayScrollbarLayers
)
2433 TEST_F(WebFrameTest
, updateOverlayScrollbarLayers
)
2436 UseMockScrollbarSettings mockScrollbarSettings
;
2438 registerMockedHttpURLLoad("large-div.html");
2440 int viewWidth
= 500;
2441 int viewHeight
= 500;
2443 OwnPtr
<FakeCompositingWebViewClient
> fakeCompositingWebViewClient
= adoptPtr(new FakeCompositingWebViewClient());
2444 FrameTestHelpers::WebViewHelper webViewHelper
;
2445 webViewHelper
.initialize(true, 0, fakeCompositingWebViewClient
.get(), &configueCompositingWebView
);
2447 webViewHelper
.webView()->resize(WebSize(viewWidth
, viewHeight
));
2448 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "large-div.html");
2450 FrameView
* view
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
2451 EXPECT_TRUE(view
->layoutView()->compositor()->layerForHorizontalScrollbar());
2452 EXPECT_TRUE(view
->layoutView()->compositor()->layerForVerticalScrollbar());
2454 webViewHelper
.webView()->resize(WebSize(viewWidth
* 10, viewHeight
* 10));
2455 webViewHelper
.webView()->layout();
2456 EXPECT_FALSE(view
->layoutView()->compositor()->layerForHorizontalScrollbar());
2457 EXPECT_FALSE(view
->layoutView()->compositor()->layerForVerticalScrollbar());
2460 void setScaleAndScrollAndLayout(WebViewImpl
* webView
, WebPoint scroll
, float scale
)
2462 webView
->setPageScaleFactor(scale
);
2463 webView
->mainFrame()->setScrollOffset(WebSize(scroll
.x
, scroll
.y
));
2467 void simulatePageScale(WebViewImpl
* webViewImpl
, float& scale
)
2469 IntSize scrollDelta
= webViewImpl
->fakePageScaleAnimationTargetPositionForTesting() - webViewImpl
->mainFrameImpl()->frameView()->scrollPosition();
2470 float scaleDelta
= webViewImpl
->fakePageScaleAnimationPageScaleForTesting() / webViewImpl
->pageScaleFactor();
2471 webViewImpl
->applyViewportDeltas(WebFloatSize(), FloatSize(scrollDelta
), WebFloatSize(), scaleDelta
, 0);
2472 scale
= webViewImpl
->pageScaleFactor();
2475 void simulateMultiTargetZoom(WebViewImpl
* webViewImpl
, const WebRect
& rect
, float& scale
)
2477 if (webViewImpl
->zoomToMultipleTargetsRect(rect
))
2478 simulatePageScale(webViewImpl
, scale
);
2481 void simulateDoubleTap(WebViewImpl
* webViewImpl
, WebPoint
& point
, float& scale
)
2483 webViewImpl
->animateDoubleTapZoom(point
);
2484 EXPECT_TRUE(webViewImpl
->fakeDoubleTapAnimationPendingForTesting());
2485 simulatePageScale(webViewImpl
, scale
);
2488 TEST_P(ParameterizedWebFrameTest
, DivAutoZoomParamsTest
)
2490 registerMockedHttpURLLoad("get_scale_for_auto_zoom_into_div_test.html");
2492 const float deviceScaleFactor
= 2.0f
;
2493 int viewportWidth
= 640 / deviceScaleFactor
;
2494 int viewportHeight
= 1280 / deviceScaleFactor
;
2495 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2496 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2497 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_for_auto_zoom_into_div_test.html", false, 0, 0, configureAndroid
);
2498 webViewHelper
.webView()->setDeviceScaleFactor(deviceScaleFactor
);
2499 webViewHelper
.webView()->setDefaultPageScaleLimits(0.01f
, 4);
2500 webViewHelper
.webView()->setPageScaleFactor(0.5f
);
2501 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2502 webViewHelper
.webView()->layout();
2504 WebRect
wideDiv(200, 100, 400, 150);
2505 WebRect
tallDiv(200, 300, 400, 800);
2506 WebPoint
doubleTapPointWide(wideDiv
.x
+ 50, wideDiv
.y
+ 50);
2507 WebPoint
doubleTapPointTall(tallDiv
.x
+ 50, tallDiv
.y
+ 50);
2511 float doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2513 // Test double-tap zooming into wide div.
2514 WebRect wideBlockBound
= webViewHelper
.webViewImpl()->computeBlockBound(doubleTapPointWide
, false);
2515 webViewHelper
.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide
.x
, doubleTapPointWide
.y
), wideBlockBound
, touchPointPadding
, doubleTapZoomAlreadyLegibleScale
, scale
, scroll
);
2516 // The div should horizontally fill the screen (modulo margins), and
2517 // vertically centered (modulo integer rounding).
2518 EXPECT_NEAR(viewportWidth
/ (float) wideDiv
.width
, scale
, 0.1);
2519 EXPECT_NEAR(wideDiv
.x
, scroll
.x
, 20);
2520 EXPECT_EQ(0, scroll
.y
);
2522 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), scroll
, scale
);
2524 // Test zoom out back to minimum scale.
2525 wideBlockBound
= webViewHelper
.webViewImpl()->computeBlockBound(doubleTapPointWide
, false);
2526 webViewHelper
.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointWide
.x
, doubleTapPointWide
.y
), wideBlockBound
, touchPointPadding
, doubleTapZoomAlreadyLegibleScale
, scale
, scroll
);
2527 // FIXME: Looks like we are missing EXPECTs here.
2529 scale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor();
2530 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), scale
);
2532 // Test double-tap zooming into tall div.
2533 WebRect tallBlockBound
= webViewHelper
.webViewImpl()->computeBlockBound(doubleTapPointTall
, false);
2534 webViewHelper
.webViewImpl()->computeScaleAndScrollForBlockRect(WebPoint(doubleTapPointTall
.x
, doubleTapPointTall
.y
), tallBlockBound
, touchPointPadding
, doubleTapZoomAlreadyLegibleScale
, scale
, scroll
);
2535 // The div should start at the top left of the viewport.
2536 EXPECT_NEAR(viewportWidth
/ (float) tallDiv
.width
, scale
, 0.1);
2537 EXPECT_NEAR(tallDiv
.x
, scroll
.x
, 20);
2538 EXPECT_NEAR(tallDiv
.y
, scroll
.y
, 20);
2541 TEST_P(ParameterizedWebFrameTest
, DivAutoZoomWideDivTest
)
2543 registerMockedHttpURLLoad("get_wide_div_for_auto_zoom_test.html");
2545 const float deviceScaleFactor
= 2.0f
;
2546 int viewportWidth
= 640 / deviceScaleFactor
;
2547 int viewportHeight
= 1280 / deviceScaleFactor
;
2548 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2549 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2550 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_wide_div_for_auto_zoom_test.html", false, 0, 0, configureAndroid
);
2551 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2552 webViewHelper
.webView()->setDeviceScaleFactor(deviceScaleFactor
);
2553 webViewHelper
.webView()->setPageScaleFactor(1.0f
);
2554 webViewHelper
.webView()->layout();
2556 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2558 float doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2560 WebRect
div(0, 100, viewportWidth
, 150);
2561 WebPoint
point(div
.x
+ 50, div
.y
+ 50);
2563 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2565 simulateDoubleTap(webViewHelper
.webViewImpl(), point
, scale
);
2566 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2567 simulateDoubleTap(webViewHelper
.webViewImpl(), point
, scale
);
2568 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2571 TEST_P(ParameterizedWebFrameTest
, DivAutoZoomVeryTallTest
)
2573 // When a block is taller than the viewport and a zoom targets a lower part
2574 // of it, then we should keep the target point onscreen instead of snapping
2575 // back up the top of the block.
2576 registerMockedHttpURLLoad("very_tall_div.html");
2578 const float deviceScaleFactor
= 2.0f
;
2579 int viewportWidth
= 640 / deviceScaleFactor
;
2580 int viewportHeight
= 1280 / deviceScaleFactor
;
2581 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2582 webViewHelper
.initializeAndLoad(m_baseURL
+ "very_tall_div.html", true, 0, 0, configureAndroid
);
2583 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2584 webViewHelper
.webView()->setDeviceScaleFactor(deviceScaleFactor
);
2585 webViewHelper
.webView()->setPageScaleFactor(1.0f
);
2586 webViewHelper
.webView()->layout();
2588 WebRect
div(200, 300, 400, 5000);
2589 WebPoint
point(div
.x
+ 50, div
.y
+ 3000);
2593 WebRect blockBound
= webViewHelper
.webViewImpl()->computeBlockBound(point
, true);
2594 webViewHelper
.webViewImpl()->computeScaleAndScrollForBlockRect(point
, blockBound
, 0, 1.0f
, scale
, scroll
);
2595 EXPECT_EQ(scale
, 1.0f
);
2596 EXPECT_EQ(scroll
.y
, 2660);
2599 TEST_F(WebFrameTest
, DivAutoZoomMultipleDivsTest
)
2601 registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
2603 const float deviceScaleFactor
= 2.0f
;
2604 int viewportWidth
= 640 / deviceScaleFactor
;
2605 int viewportHeight
= 1280 / deviceScaleFactor
;
2606 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2607 FrameTestHelpers::WebViewHelper webViewHelper
;
2608 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_multiple_divs_for_auto_zoom_test.html", false, 0, 0, configureAndroid
);
2609 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2610 webViewHelper
.webView()->setDefaultPageScaleLimits(0.5f
, 4);
2611 webViewHelper
.webView()->setDeviceScaleFactor(deviceScaleFactor
);
2612 webViewHelper
.webView()->setPageScaleFactor(0.5f
);
2613 webViewHelper
.webView()->setMaximumLegibleScale(1.f
);
2614 webViewHelper
.webView()->layout();
2616 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2618 WebRect
topDiv(200, 100, 200, 150);
2619 WebRect
bottomDiv(200, 300, 200, 150);
2620 WebPoint
topPoint(topDiv
.x
+ 50, topDiv
.y
+ 50);
2621 WebPoint
bottomPoint(bottomDiv
.x
+ 50, bottomDiv
.y
+ 50);
2623 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2625 // Test double tap on two different divs
2626 // After first zoom, we should go back to minimum page scale with a second double tap.
2627 simulateDoubleTap(webViewHelper
.webViewImpl(), topPoint
, scale
);
2628 EXPECT_FLOAT_EQ(1, scale
);
2629 simulateDoubleTap(webViewHelper
.webViewImpl(), bottomPoint
, scale
);
2630 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2632 // If the user pinch zooms after double tap, a second double tap should zoom back to the div.
2633 simulateDoubleTap(webViewHelper
.webViewImpl(), topPoint
, scale
);
2634 EXPECT_FLOAT_EQ(1, scale
);
2635 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 0.6f
, 0);
2636 simulateDoubleTap(webViewHelper
.webViewImpl(), bottomPoint
, scale
);
2637 EXPECT_FLOAT_EQ(1, scale
);
2638 simulateDoubleTap(webViewHelper
.webViewImpl(), bottomPoint
, scale
);
2639 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2641 // If we didn't yet get an auto-zoom update and a second double-tap arrives, should go back to minimum scale.
2642 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2643 webViewHelper
.webViewImpl()->animateDoubleTapZoom(topPoint
);
2644 EXPECT_TRUE(webViewHelper
.webViewImpl()->fakeDoubleTapAnimationPendingForTesting());
2645 simulateDoubleTap(webViewHelper
.webViewImpl(), bottomPoint
, scale
);
2646 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2649 TEST_F(WebFrameTest
, DivAutoZoomScaleBoundsTest
)
2651 registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");
2653 int viewportWidth
= 320;
2654 int viewportHeight
= 480;
2655 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2656 FrameTestHelpers::WebViewHelper webViewHelper
;
2657 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid
);
2658 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2659 webViewHelper
.webView()->setDeviceScaleFactor(1.5f
);
2660 webViewHelper
.webView()->setMaximumLegibleScale(1.f
);
2661 webViewHelper
.webView()->layout();
2663 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2665 WebRect
div(200, 100, 200, 150);
2666 WebPoint
doubleTapPoint(div
.x
+ 50, div
.y
+ 50);
2669 // Test double tap scale bounds.
2670 // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1
2671 webViewHelper
.webView()->setDefaultPageScaleLimits(0.5f
, 4);
2672 webViewHelper
.webView()->layout();
2673 float doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2674 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2675 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2676 EXPECT_FLOAT_EQ(1, scale
);
2677 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2678 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2679 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2680 EXPECT_FLOAT_EQ(1, scale
);
2682 // Zoom in to reset double_tap_zoom_in_effect flag.
2683 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2684 // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale
2685 webViewHelper
.webView()->setDefaultPageScaleLimits(1.1f
, 4);
2686 webViewHelper
.webView()->layout();
2687 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2688 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2689 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2690 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2691 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2692 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2693 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2694 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2696 // Zoom in to reset double_tap_zoom_in_effect flag.
2697 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2698 // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
2699 webViewHelper
.webView()->setDefaultPageScaleLimits(0.95f
, 4);
2700 webViewHelper
.webView()->layout();
2701 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2702 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2703 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2704 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2705 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2706 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2707 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2708 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2711 TEST_F(WebFrameTest
, DivAutoZoomScaleLegibleScaleTest
)
2713 registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");
2715 int viewportWidth
= 320;
2716 int viewportHeight
= 480;
2717 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2718 float maximumLegibleScaleFactor
= 1.13f
;
2719 FrameTestHelpers::WebViewHelper webViewHelper
;
2720 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid
);
2721 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2722 webViewHelper
.webView()->setMaximumLegibleScale(maximumLegibleScaleFactor
);
2723 webViewHelper
.webView()->layout();
2725 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2726 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(true);
2728 WebRect
div(200, 100, 200, 150);
2729 WebPoint
doubleTapPoint(div
.x
+ 50, div
.y
+ 50);
2732 // Test double tap scale bounds.
2733 // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 < maximumLegibleScaleFactor
2734 float legibleScale
= maximumLegibleScaleFactor
;
2735 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2736 float doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2737 webViewHelper
.webView()->setDefaultPageScaleLimits(0.5f
, 4);
2738 webViewHelper
.webView()->layout();
2739 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2740 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2741 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2742 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2743 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2744 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2746 // Zoom in to reset double_tap_zoom_in_effect flag.
2747 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2748 // 1 < maximumLegibleScaleFactor < minimumPageScale < doubleTapZoomAlreadyLegibleScale
2749 webViewHelper
.webView()->setDefaultPageScaleLimits(1.0f
, 4);
2750 webViewHelper
.webView()->layout();
2751 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2752 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2753 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2754 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2755 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2756 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2757 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2758 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2760 // Zoom in to reset double_tap_zoom_in_effect flag.
2761 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2762 // minimumPageScale < 1 < maximumLegibleScaleFactor < doubleTapZoomAlreadyLegibleScale
2763 webViewHelper
.webView()->setDefaultPageScaleLimits(0.95f
, 4);
2764 webViewHelper
.webView()->layout();
2765 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2766 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2767 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2768 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2769 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2770 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2771 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2772 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2774 // Zoom in to reset double_tap_zoom_in_effect flag.
2775 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2776 // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < maximumLegibleScaleFactor
2777 webViewHelper
.webView()->setDefaultPageScaleLimits(0.9f
, 4);
2778 webViewHelper
.webView()->layout();
2779 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2780 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2781 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2782 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2783 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2784 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2785 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2786 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2790 TEST_F(WebFrameTest
, DivAutoZoomScaleFontScaleFactorTest
)
2792 registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");
2794 int viewportWidth
= 320;
2795 int viewportHeight
= 480;
2796 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2797 float accessibilityFontScaleFactor
= 1.13f
;
2798 FrameTestHelpers::WebViewHelper webViewHelper
;
2799 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_bounds_check_for_auto_zoom_test.html", false, 0, 0, configureAndroid
);
2800 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2801 webViewHelper
.webView()->setMaximumLegibleScale(1.f
);
2802 webViewHelper
.webView()->layout();
2804 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2805 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(true);
2806 webViewHelper
.webViewImpl()->page()->settings().setAccessibilityFontScaleFactor(accessibilityFontScaleFactor
);
2808 WebRect
div(200, 100, 200, 150);
2809 WebPoint
doubleTapPoint(div
.x
+ 50, div
.y
+ 50);
2812 // Test double tap scale bounds.
2813 // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 < accessibilityFontScaleFactor
2814 float legibleScale
= accessibilityFontScaleFactor
;
2815 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2816 float doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2817 webViewHelper
.webView()->setDefaultPageScaleLimits(0.5f
, 4);
2818 webViewHelper
.webView()->layout();
2819 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2820 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2821 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2822 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2823 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2824 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2826 // Zoom in to reset double_tap_zoom_in_effect flag.
2827 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2828 // 1 < accessibilityFontScaleFactor < minimumPageScale < doubleTapZoomAlreadyLegibleScale
2829 webViewHelper
.webView()->setDefaultPageScaleLimits(1.0f
, 4);
2830 webViewHelper
.webView()->layout();
2831 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2832 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2833 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2834 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2835 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2836 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2837 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2838 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2840 // Zoom in to reset double_tap_zoom_in_effect flag.
2841 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2842 // minimumPageScale < 1 < accessibilityFontScaleFactor < doubleTapZoomAlreadyLegibleScale
2843 webViewHelper
.webView()->setDefaultPageScaleLimits(0.95f
, 4);
2844 webViewHelper
.webView()->layout();
2845 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2846 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2847 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2848 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2849 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2850 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2851 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2852 EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale
, scale
);
2854 // Zoom in to reset double_tap_zoom_in_effect flag.
2855 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.1f
, 0);
2856 // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < accessibilityFontScaleFactor
2857 webViewHelper
.webView()->setDefaultPageScaleLimits(0.9f
, 4);
2858 webViewHelper
.webView()->layout();
2859 doubleTapZoomAlreadyLegibleScale
= webViewHelper
.webViewImpl()->minimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio
;
2860 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2861 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2862 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2863 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2864 EXPECT_FLOAT_EQ(webViewHelper
.webViewImpl()->minimumPageScaleFactor(), scale
);
2865 simulateDoubleTap(webViewHelper
.webViewImpl(), doubleTapPoint
, scale
);
2866 EXPECT_FLOAT_EQ(legibleScale
, scale
);
2869 TEST_P(ParameterizedWebFrameTest
, BlockBoundTest
)
2871 registerMockedHttpURLLoad("block_bound.html");
2873 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2874 webViewHelper
.initializeAndLoad(m_baseURL
+ "block_bound.html", false, 0, 0, configureAndroid
);
2876 IntRect rectBack
= IntRect(0, 0, 200, 200);
2877 IntRect rectLeftTop
= IntRect(10, 10, 80, 80);
2878 IntRect rectRightBottom
= IntRect(110, 110, 80, 80);
2881 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(9, 9), true));
2882 EXPECT_RECT_EQ(rectBack
, blockBound
);
2884 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(10, 10), true));
2885 EXPECT_RECT_EQ(rectLeftTop
, blockBound
);
2887 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(50, 50), true));
2888 EXPECT_RECT_EQ(rectLeftTop
, blockBound
);
2890 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(89, 89), true));
2891 EXPECT_RECT_EQ(rectLeftTop
, blockBound
);
2893 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(90, 90), true));
2894 EXPECT_RECT_EQ(rectBack
, blockBound
);
2896 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(109, 109), true));
2897 EXPECT_RECT_EQ(rectBack
, blockBound
);
2899 blockBound
= IntRect(webViewHelper
.webViewImpl()->computeBlockBound(WebPoint(110, 110), true));
2900 EXPECT_RECT_EQ(rectRightBottom
, blockBound
);
2903 TEST_P(ParameterizedWebFrameTest
, DivMultipleTargetZoomMultipleDivsTest
)
2905 registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");
2907 const float deviceScaleFactor
= 2.0f
;
2908 int viewportWidth
= 640 / deviceScaleFactor
;
2909 int viewportHeight
= 1280 / deviceScaleFactor
;
2910 float doubleTapZoomAlreadyLegibleRatio
= 1.2f
;
2911 FrameTestHelpers::WebViewHelper
webViewHelper(this);
2912 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_multiple_divs_for_auto_zoom_test.html");
2913 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2914 webViewHelper
.webView()->setDefaultPageScaleLimits(0.5f
, 4);
2915 webViewHelper
.webView()->setDeviceScaleFactor(deviceScaleFactor
);
2916 webViewHelper
.webView()->setPageScaleFactor(0.5f
);
2917 webViewHelper
.webView()->setMaximumLegibleScale(1.f
);
2918 webViewHelper
.webView()->layout();
2920 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2922 WebRect
viewportRect(0, 0, viewportWidth
, viewportHeight
);
2923 WebRect
topDiv(200, 100, 200, 150);
2924 WebRect
bottomDiv(200, 300, 200, 150);
2926 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), (webViewHelper
.webViewImpl()->minimumPageScaleFactor()) * (1 + doubleTapZoomAlreadyLegibleRatio
) / 2);
2928 simulateMultiTargetZoom(webViewHelper
.webViewImpl(), topDiv
, scale
);
2929 EXPECT_FLOAT_EQ(1, scale
);
2930 simulateMultiTargetZoom(webViewHelper
.webViewImpl(), bottomDiv
, scale
);
2931 EXPECT_FLOAT_EQ(1, scale
);
2932 simulateMultiTargetZoom(webViewHelper
.webViewImpl(), viewportRect
, scale
);
2933 EXPECT_FLOAT_EQ(1, scale
);
2934 webViewHelper
.webViewImpl()->setPageScaleFactor(webViewHelper
.webViewImpl()->minimumPageScaleFactor());
2935 simulateMultiTargetZoom(webViewHelper
.webViewImpl(), topDiv
, scale
);
2936 EXPECT_FLOAT_EQ(1, scale
);
2939 TEST_F(WebFrameTest
, DontZoomInOnFocusedInTouchAction
)
2941 registerMockedHttpURLLoad("textbox_in_touch_action.html");
2943 int viewportWidth
= 600;
2944 int viewportHeight
= 1000;
2946 FrameTestHelpers::WebViewHelper webViewHelper
;
2947 webViewHelper
.initializeAndLoad(m_baseURL
+ "textbox_in_touch_action.html");
2948 webViewHelper
.webViewImpl()->setDefaultPageScaleLimits(0.25f
, 4);
2949 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
2950 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
2951 webViewHelper
.webViewImpl()->settings()->setAutoZoomFocusedNodeToLegibleScale(true);
2952 webViewHelper
.webViewImpl()->resize(WebSize(viewportWidth
, viewportHeight
));
2954 float initialScale
= webViewHelper
.webViewImpl()->pageScaleFactor();
2956 // Focus the first textbox that's in a touch-action: pan-x ancestor, this
2957 // shouldn't cause an autozoom since pan-x disables pinch-zoom.
2958 webViewHelper
.webViewImpl()->advanceFocus(false);
2959 webViewHelper
.webViewImpl()->scrollFocusedNodeIntoRect(WebRect());
2960 EXPECT_EQ(webViewHelper
.webViewImpl()->fakePageScaleAnimationPageScaleForTesting(), 0);
2962 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
2963 ASSERT_EQ(initialScale
, webViewHelper
.webViewImpl()->pageScaleFactor());
2965 // Focus the second textbox that's in a touch-action: manipulation ancestor,
2966 // this should cause an autozoom since it allows pinch-zoom.
2967 webViewHelper
.webViewImpl()->advanceFocus(false);
2968 webViewHelper
.webViewImpl()->scrollFocusedNodeIntoRect(WebRect());
2969 EXPECT_GT(webViewHelper
.webViewImpl()->fakePageScaleAnimationPageScaleForTesting(), initialScale
);
2971 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
2972 ASSERT_EQ(initialScale
, webViewHelper
.webViewImpl()->pageScaleFactor());
2974 // Focus the third textbox that has a touch-action: pan-x ancestor, this
2975 // should cause an autozoom since it's seperated from the node with the
2976 // touch-action by an overflow:scroll element.
2977 webViewHelper
.webView()->advanceFocus(false);
2978 webViewHelper
.webViewImpl()->scrollFocusedNodeIntoRect(WebRect());
2979 EXPECT_GT(webViewHelper
.webViewImpl()->fakePageScaleAnimationPageScaleForTesting(), initialScale
);
2983 TEST_F(WebFrameTest
, DivScrollIntoEditableTest
)
2985 registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");
2987 const bool autoZoomToLegibleScale
= true;
2988 int viewportWidth
= 450;
2989 int viewportHeight
= 300;
2990 float leftBoxRatio
= 0.3f
;
2991 int caretPadding
= 10;
2992 float minReadableCaretHeight
= 16.0f
;
2993 FrameTestHelpers::WebViewHelper webViewHelper
;
2994 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_for_zoom_into_editable_test.html");
2995 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
2996 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
2997 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 4);
2999 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
3001 WebRect
editBoxWithText(200, 200, 250, 20);
3002 WebRect
editBoxWithNoText(200, 250, 250, 20);
3004 // Test scrolling the focused node
3005 // The edit box is shorter and narrower than the viewport when legible.
3006 webViewHelper
.webView()->advanceFocus(false);
3007 // Set the caret to the end of the input box.
3008 webViewHelper
.webView()->mainFrame()->document().getElementById("EditBoxWithText").to
<WebInputElement
>().setSelectionRange(1000, 1000);
3009 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), 1);
3010 WebRect rect
, caret
;
3011 webViewHelper
.webViewImpl()->selectionBounds(caret
, rect
);
3013 // Set the page scale to be smaller than the minimal readable scale.
3014 float initialScale
= minReadableCaretHeight
/ caret
.height
* 0.5f
;
3015 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
3020 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3021 EXPECT_TRUE(needAnimation
);
3022 // The edit box should be left aligned with a margin for possible label.
3023 int hScroll
= editBoxWithText
.x
- leftBoxRatio
* viewportWidth
/ scale
;
3024 EXPECT_NEAR(hScroll
, scroll
.x(), 2);
3025 int vScroll
= editBoxWithText
.y
- (viewportHeight
/ scale
- editBoxWithText
.height
) / 2;
3026 EXPECT_NEAR(vScroll
, scroll
.y(), 2);
3027 EXPECT_NEAR(minReadableCaretHeight
/ caret
.height
, scale
, 0.1);
3029 // The edit box is wider than the viewport when legible.
3030 viewportWidth
= 200;
3031 viewportHeight
= 150;
3032 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
3033 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
3034 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3035 EXPECT_TRUE(needAnimation
);
3036 // The caret should be right aligned since the caret would be offscreen when the edit box is left aligned.
3037 hScroll
= caret
.x
+ caret
.width
+ caretPadding
- viewportWidth
/ scale
;
3038 EXPECT_NEAR(hScroll
, scroll
.x(), 2);
3039 EXPECT_NEAR(minReadableCaretHeight
/ caret
.height
, scale
, 0.1);
3041 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
3042 // Move focus to edit box with text.
3043 webViewHelper
.webView()->advanceFocus(false);
3044 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3045 EXPECT_TRUE(needAnimation
);
3046 // The edit box should be left aligned.
3047 hScroll
= editBoxWithNoText
.x
;
3048 EXPECT_NEAR(hScroll
, scroll
.x(), 2);
3049 vScroll
= editBoxWithNoText
.y
- (viewportHeight
/ scale
- editBoxWithNoText
.height
) / 2;
3050 EXPECT_NEAR(vScroll
, scroll
.y(), 2);
3051 EXPECT_NEAR(minReadableCaretHeight
/ caret
.height
, scale
, 0.1);
3053 // Move focus back to the first edit box.
3054 webViewHelper
.webView()->advanceFocus(true);
3055 // Zoom out slightly.
3056 const float withinToleranceScale
= scale
* 0.9f
;
3057 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), scroll
, withinToleranceScale
);
3058 // Move focus back to the second edit box.
3059 webViewHelper
.webView()->advanceFocus(false);
3060 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3061 // The scale should not be adjusted as the zoomed out scale was sufficiently close to the previously focused scale.
3062 EXPECT_FALSE(needAnimation
);
3065 TEST_F(WebFrameTest
, DivScrollIntoEditablePreservePageScaleTest
)
3067 registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");
3069 const bool autoZoomToLegibleScale
= true;
3070 const int viewportWidth
= 450;
3071 const int viewportHeight
= 300;
3072 const float minReadableCaretHeight
= 16.0f
;
3073 FrameTestHelpers::WebViewHelper webViewHelper
;
3074 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_for_zoom_into_editable_test.html");
3075 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
3076 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
3077 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
3079 const WebRect
editBoxWithText(200, 200, 250, 20);
3081 webViewHelper
.webView()->advanceFocus(false);
3082 // Set the caret to the begining of the input box.
3083 webViewHelper
.webView()->mainFrame()->document().getElementById("EditBoxWithText").to
<WebInputElement
>().setSelectionRange(0, 0);
3084 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), 1);
3085 WebRect rect
, caret
;
3086 webViewHelper
.webViewImpl()->selectionBounds(caret
, rect
);
3088 // Set the page scale to be twice as large as the minimal readable scale.
3089 float newScale
= minReadableCaretHeight
/ caret
.height
* 2.0;
3090 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), newScale
);
3095 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3096 EXPECT_TRUE(needAnimation
);
3097 // Edit box and caret should be left alinged
3098 int hScroll
= editBoxWithText
.x
;
3099 EXPECT_NEAR(hScroll
, scroll
.x(), 1);
3100 int vScroll
= editBoxWithText
.y
- (viewportHeight
/ scale
- editBoxWithText
.height
) / 2;
3101 EXPECT_NEAR(vScroll
, scroll
.y(), 1);
3102 // Page scale have to be unchanged
3103 EXPECT_EQ(newScale
, scale
);
3105 // Set page scale and scroll such that edit box will be under the screen
3108 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(hScroll
, 0), newScale
);
3109 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3110 EXPECT_TRUE(needAnimation
);
3111 // Horizontal scroll have to be the same
3112 EXPECT_NEAR(hScroll
, scroll
.x(), 1);
3113 vScroll
= editBoxWithText
.y
- (viewportHeight
/ scale
- editBoxWithText
.height
) / 2;
3114 EXPECT_NEAR(vScroll
, scroll
.y(), 1);
3115 // Page scale have to be unchanged
3116 EXPECT_EQ(newScale
, scale
);
3119 // Tests the scroll into view functionality when autoZoomeFocusedNodeToLegibleScale set
3120 // to false. i.e. The path non-Android platforms take.
3121 TEST_F(WebFrameTest
, DivScrollIntoEditableTestZoomToLegibleScaleDisabled
)
3123 registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");
3125 const bool autoZoomToLegibleScale
= false;
3126 int viewportWidth
= 100;
3127 int viewportHeight
= 100;
3128 float leftBoxRatio
= 0.3f
;
3129 FrameTestHelpers::WebViewHelper webViewHelper
;
3130 webViewHelper
.initializeAndLoad(m_baseURL
+ "get_scale_for_zoom_into_editable_test.html");
3131 webViewHelper
.webViewImpl()->page()->settings().setTextAutosizingEnabled(false);
3132 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
3133 webViewHelper
.webView()->setDefaultPageScaleLimits(0.25f
, 4);
3135 webViewHelper
.webViewImpl()->enableFakePageScaleAnimationForTesting(true);
3137 WebRect
editBoxWithText(200, 200, 250, 20);
3138 WebRect
editBoxWithNoText(200, 250, 250, 20);
3140 // Test scrolling the focused node
3141 // Since we're zoomed out, the caret is considered too small to be legible and so we'd
3142 // normally zoom in. Make sure we don't change scale since the auto-zoom setting is off.
3144 // Focus the second empty textbox.
3145 webViewHelper
.webView()->advanceFocus(false);
3146 webViewHelper
.webView()->advanceFocus(false);
3148 // Set the page scale to be smaller than the minimal readable scale.
3149 float initialScale
= 0.25f
;
3150 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), WebPoint(0, 0), initialScale
);
3155 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3157 // There should be no change in page scale.
3158 EXPECT_EQ(initialScale
, scale
);
3159 // The edit box should be left aligned with a margin for possible label.
3160 EXPECT_TRUE(needAnimation
);
3161 int hScroll
= editBoxWithNoText
.x
- leftBoxRatio
* viewportWidth
/ scale
;
3162 EXPECT_NEAR(hScroll
, scroll
.x(), 2);
3163 int vScroll
= editBoxWithNoText
.y
- (viewportHeight
/ scale
- editBoxWithNoText
.height
) / 2;
3164 EXPECT_NEAR(vScroll
, scroll
.y(), 2);
3166 setScaleAndScrollAndLayout(webViewHelper
.webViewImpl(), scroll
, scale
);
3168 // Select the first textbox.
3169 webViewHelper
.webView()->advanceFocus(true);
3170 WebRect rect
, caret
;
3171 webViewHelper
.webViewImpl()->selectionBounds(caret
, rect
);
3172 webViewHelper
.webViewImpl()->computeScaleAndScrollForFocusedNode(webViewHelper
.webViewImpl()->focusedElement(), autoZoomToLegibleScale
, scale
, scroll
, needAnimation
);
3174 // There should be no change at all since the textbox is fully visible already.
3175 EXPECT_EQ(initialScale
, scale
);
3176 EXPECT_FALSE(needAnimation
);
3179 TEST_P(ParameterizedWebFrameTest
, CharacterIndexAtPointWithPinchZoom
)
3181 registerMockedHttpURLLoad("sometext.html");
3183 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3184 webViewHelper
.initializeAndLoad(m_baseURL
+ "sometext.html");
3185 webViewHelper
.webViewImpl()->resize(WebSize(640, 480));
3186 webViewHelper
.webViewImpl()->layout();
3189 webViewHelper
.webViewImpl()->setPageScaleFactor(2);
3190 webViewHelper
.webViewImpl()->setVisualViewportOffset(WebFloatPoint(50, 60));
3195 WebFrame
* mainFrame
= webViewHelper
.webViewImpl()->mainFrame();
3196 size_t ix
= mainFrame
->characterIndexForPoint(WebPoint(320, 388));
3201 TEST_P(ParameterizedWebFrameTest
, FirstRectForCharacterRangeWithPinchZoom
)
3203 registerMockedHttpURLLoad("textbox.html");
3205 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3206 webViewHelper
.initializeAndLoad(m_baseURL
+ "textbox.html", true);
3207 webViewHelper
.webViewImpl()->resize(WebSize(640, 480));
3209 WebFrame
* mainFrame
= webViewHelper
.webViewImpl()->mainFrame();
3210 mainFrame
->executeScript(WebScriptSource("selectRange();"));
3213 mainFrame
->firstRectForCharacterRange(0, 5, oldRect
);
3215 WebFloatPoint
visualOffset(100, 130);
3217 webViewHelper
.webViewImpl()->setPageScaleFactor(scale
);
3218 webViewHelper
.webViewImpl()->setVisualViewportOffset(visualOffset
);
3224 mainFrame
->firstRectForCharacterRange(0, 5, rect
);
3226 EXPECT_EQ((oldRect
.x
- visualOffset
.x
) * scale
, rect
.x
);
3227 EXPECT_EQ((oldRect
.y
- visualOffset
.y
) * scale
, rect
.y
);
3228 EXPECT_EQ(oldRect
.width
*scale
, rect
.width
);
3229 EXPECT_EQ(oldRect
.height
*scale
, rect
.height
);
3231 class TestReloadDoesntRedirectWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
3233 WebNavigationPolicy
decidePolicyForNavigation(const NavigationPolicyInfo
& info
) override
3235 EXPECT_FALSE(info
.isRedirect
);
3236 return WebNavigationPolicyCurrentTab
;
3240 TEST_P(ParameterizedWebFrameTest
, ReloadDoesntSetRedirect
)
3242 // Test for case in http://crbug.com/73104. Reloading a frame very quickly
3243 // would sometimes call decidePolicyForNavigation with isRedirect=true
3244 registerMockedHttpURLLoad("form.html");
3246 TestReloadDoesntRedirectWebFrameClient webFrameClient
;
3247 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3248 webViewHelper
.initializeAndLoad(m_baseURL
+ "form.html", false, &webFrameClient
);
3250 webViewHelper
.webView()->mainFrame()->reload(true);
3251 // start another reload before request is delivered.
3252 FrameTestHelpers::reloadFrameIgnoringCache(webViewHelper
.webView()->mainFrame());
3255 class ReloadWithOverrideURLTask
: public WebTaskRunner::Task
{
3257 ReloadWithOverrideURLTask(WebFrame
* frame
, const KURL
& url
, bool ignoreCache
)
3258 : m_frame(frame
), m_url(url
), m_ignoreCache(ignoreCache
)
3264 m_frame
->reloadWithOverrideURL(m_url
, m_ignoreCache
);
3268 WebFrame
* const m_frame
;
3270 const bool m_ignoreCache
;
3273 class ClearScrollStateOnCommitWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
3275 void didCommitProvisionalLoad(WebLocalFrame
* frame
, const WebHistoryItem
&, WebHistoryCommitType
) override
3277 frame
->view()->resetScrollAndScaleState();
3281 TEST_F(WebFrameTest
, ReloadWithOverrideURLPreservesState
)
3283 const std::string firstURL
= "200-by-300.html";
3284 const std::string secondURL
= "content-width-1000.html";
3285 const std::string thirdURL
= "very_tall_div.html";
3286 const float pageScaleFactor
= 1.1684f
;
3287 const int pageWidth
= 120;
3288 const int pageHeight
= 100;
3290 registerMockedHttpURLLoad(firstURL
);
3291 registerMockedHttpURLLoad(secondURL
);
3292 registerMockedHttpURLLoad(thirdURL
);
3294 FrameTestHelpers::WebViewHelper webViewHelper
;
3295 ClearScrollStateOnCommitWebFrameClient client
;
3296 webViewHelper
.initializeAndLoad(m_baseURL
+ firstURL
, true, &client
);
3297 webViewHelper
.webViewImpl()->resize(WebSize(pageWidth
, pageHeight
));
3298 webViewHelper
.webViewImpl()->mainFrame()->setScrollOffset(WebSize(pageWidth
/ 4, pageHeight
/ 4));
3299 webViewHelper
.webViewImpl()->setPageScaleFactor(pageScaleFactor
);
3301 WebSize previousOffset
= webViewHelper
.webViewImpl()->mainFrame()->scrollOffset();
3302 float previousScale
= webViewHelper
.webViewImpl()->pageScaleFactor();
3304 // Reload the page and end up at the same url. State should be propagated.
3305 Platform::current()->currentThread()->taskRunner()->postTask(
3306 FROM_HERE
, new ReloadWithOverrideURLTask(webViewHelper
.webViewImpl()->mainFrame(), toKURL(m_baseURL
+ firstURL
), false));
3307 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webViewImpl()->mainFrame());
3308 EXPECT_EQ(previousOffset
.width
, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().width
);
3309 EXPECT_EQ(previousOffset
.height
, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().height
);
3310 EXPECT_EQ(previousScale
, webViewHelper
.webViewImpl()->pageScaleFactor());
3312 // Reload the page using the cache. State should not be propagated.
3313 Platform::current()->currentThread()->taskRunner()->postTask(
3314 FROM_HERE
, new ReloadWithOverrideURLTask(webViewHelper
.webViewImpl()->mainFrame(), toKURL(m_baseURL
+ secondURL
), false));
3315 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webViewImpl()->mainFrame());
3316 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().width
);
3317 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().height
);
3318 EXPECT_EQ(1.0f
, webViewHelper
.webViewImpl()->pageScaleFactor());
3320 // Reload the page while ignoring the cache. State should not be propagated.
3321 Platform::current()->currentThread()->taskRunner()->postTask(
3322 FROM_HERE
, new ReloadWithOverrideURLTask(webViewHelper
.webViewImpl()->mainFrame(), toKURL(m_baseURL
+ thirdURL
), true));
3323 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webViewImpl()->mainFrame());
3324 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().width
);
3325 EXPECT_EQ(0, webViewHelper
.webViewImpl()->mainFrame()->scrollOffset().height
);
3326 EXPECT_EQ(1.0f
, webViewHelper
.webViewImpl()->pageScaleFactor());
3329 TEST_P(ParameterizedWebFrameTest
, ReloadWhileProvisional
)
3331 // Test that reloading while the previous load is still pending does not cause the initial
3332 // request to get lost.
3333 registerMockedHttpURLLoad("fixed_layout.html");
3335 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3336 webViewHelper
.initialize();
3337 WebURLRequest request
;
3338 request
.initialize();
3339 request
.setURL(toKURL(m_baseURL
+ "fixed_layout.html"));
3340 webViewHelper
.webView()->mainFrame()->loadRequest(request
);
3341 // start reload before first request is delivered.
3342 FrameTestHelpers::reloadFrameIgnoringCache(webViewHelper
.webView()->mainFrame());
3344 WebDataSource
* dataSource
= webViewHelper
.webView()->mainFrame()->dataSource();
3345 ASSERT_TRUE(dataSource
);
3346 EXPECT_EQ(toKURL(m_baseURL
+ "fixed_layout.html"), toKURL(dataSource
->request().url().spec()));
3349 TEST_P(ParameterizedWebFrameTest
, AppendRedirects
)
3351 const std::string firstURL
= "about:blank";
3352 const std::string secondURL
= "http://internal.test";
3354 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3355 webViewHelper
.initializeAndLoad(firstURL
, true);
3357 WebDataSource
* dataSource
= webViewHelper
.webView()->mainFrame()->dataSource();
3358 ASSERT_TRUE(dataSource
);
3359 dataSource
->appendRedirect(toKURL(secondURL
));
3361 WebVector
<WebURL
> redirects
;
3362 dataSource
->redirectChain(redirects
);
3363 ASSERT_EQ(2U, redirects
.size());
3364 EXPECT_EQ(toKURL(firstURL
), toKURL(redirects
[0].spec().data()));
3365 EXPECT_EQ(toKURL(secondURL
), toKURL(redirects
[1].spec().data()));
3368 TEST_P(ParameterizedWebFrameTest
, IframeRedirect
)
3370 registerMockedHttpURLLoad("iframe_redirect.html");
3371 registerMockedHttpURLLoad("visible_iframe.html");
3373 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3374 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframe_redirect.html", true);
3375 // Pump pending requests one more time. The test page loads script that navigates.
3376 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webView()->mainFrame());
3378 WebFrame
* iframe
= webViewHelper
.webView()->findFrameByName(WebString::fromUTF8("ifr"));
3379 ASSERT_TRUE(iframe
);
3380 WebDataSource
* iframeDataSource
= iframe
->dataSource();
3381 ASSERT_TRUE(iframeDataSource
);
3382 WebVector
<WebURL
> redirects
;
3383 iframeDataSource
->redirectChain(redirects
);
3384 ASSERT_EQ(2U, redirects
.size());
3385 EXPECT_EQ(toKURL("about:blank"), toKURL(redirects
[0].spec().data()));
3386 EXPECT_EQ(toKURL("http://internal.test/visible_iframe.html"), toKURL(redirects
[1].spec().data()));
3389 TEST_P(ParameterizedWebFrameTest
, ClearFocusedNodeTest
)
3391 registerMockedHttpURLLoad("iframe_clear_focused_node_test.html");
3392 registerMockedHttpURLLoad("autofocus_input_field_iframe.html");
3394 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3395 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframe_clear_focused_node_test.html", true);
3397 // Clear the focused node.
3398 webViewHelper
.webView()->clearFocusedElement();
3400 // Now retrieve the FocusedNode and test it should be null.
3401 EXPECT_EQ(0, webViewHelper
.webViewImpl()->focusedElement());
3404 // Implementation of WebFrameClient that tracks the v8 contexts that are created
3405 // and destroyed for verification.
3406 class ContextLifetimeTestWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
3408 struct Notification
{
3410 Notification(WebLocalFrame
* frame
, v8::Local
<v8::Context
> context
, int worldId
)
3412 , context(context
->GetIsolate(), context
)
3422 bool Equals(Notification
* other
)
3424 return other
&& frame
== other
->frame
&& context
== other
->context
&& worldId
== other
->worldId
;
3427 WebLocalFrame
* frame
;
3428 v8::Persistent
<v8::Context
> context
;
3432 ~ContextLifetimeTestWebFrameClient() override
3439 for (size_t i
= 0; i
< createNotifications
.size(); ++i
)
3440 delete createNotifications
[i
];
3442 for (size_t i
= 0; i
< releaseNotifications
.size(); ++i
)
3443 delete releaseNotifications
[i
];
3445 createNotifications
.clear();
3446 releaseNotifications
.clear();
3449 std::vector
<Notification
*> createNotifications
;
3450 std::vector
<Notification
*> releaseNotifications
;
3453 void didCreateScriptContext(WebLocalFrame
* frame
, v8::Local
<v8::Context
> context
, int extensionGroup
, int worldId
) override
3455 createNotifications
.push_back(new Notification(frame
, context
, worldId
));
3458 void willReleaseScriptContext(WebLocalFrame
* frame
, v8::Local
<v8::Context
> context
, int worldId
) override
3460 releaseNotifications
.push_back(new Notification(frame
, context
, worldId
));
3464 // TODO(aa): Deflake this test.
3465 TEST_P(ParameterizedWebFrameTest
, FLAKY_ContextNotificationsLoadUnload
)
3467 v8::HandleScope
handleScope(v8::Isolate::GetCurrent());
3469 registerMockedHttpURLLoad("context_notifications_test.html");
3470 registerMockedHttpURLLoad("context_notifications_test_frame.html");
3472 // Load a frame with an iframe, make sure we get the right create notifications.
3473 ContextLifetimeTestWebFrameClient webFrameClient
;
3474 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3475 webViewHelper
.initializeAndLoad(m_baseURL
+ "context_notifications_test.html", true, &webFrameClient
);
3477 WebFrame
* mainFrame
= webViewHelper
.webView()->mainFrame();
3478 WebFrame
* childFrame
= mainFrame
->firstChild();
3480 ASSERT_EQ(2u, webFrameClient
.createNotifications
.size());
3481 EXPECT_EQ(0u, webFrameClient
.releaseNotifications
.size());
3483 ContextLifetimeTestWebFrameClient::Notification
* firstCreateNotification
= webFrameClient
.createNotifications
[0];
3484 ContextLifetimeTestWebFrameClient::Notification
* secondCreateNotification
= webFrameClient
.createNotifications
[1];
3486 EXPECT_EQ(mainFrame
, firstCreateNotification
->frame
);
3487 EXPECT_EQ(mainFrame
->mainWorldScriptContext(), firstCreateNotification
->context
);
3488 EXPECT_EQ(0, firstCreateNotification
->worldId
);
3490 EXPECT_EQ(childFrame
, secondCreateNotification
->frame
);
3491 EXPECT_EQ(childFrame
->mainWorldScriptContext(), secondCreateNotification
->context
);
3492 EXPECT_EQ(0, secondCreateNotification
->worldId
);
3494 // Close the view. We should get two release notifications that are exactly the same as the create ones, in reverse order.
3495 webViewHelper
.reset();
3497 ASSERT_EQ(2u, webFrameClient
.releaseNotifications
.size());
3498 ContextLifetimeTestWebFrameClient::Notification
* firstReleaseNotification
= webFrameClient
.releaseNotifications
[0];
3499 ContextLifetimeTestWebFrameClient::Notification
* secondReleaseNotification
= webFrameClient
.releaseNotifications
[1];
3501 ASSERT_TRUE(firstCreateNotification
->Equals(secondReleaseNotification
));
3502 ASSERT_TRUE(secondCreateNotification
->Equals(firstReleaseNotification
));
3505 TEST_P(ParameterizedWebFrameTest
, ContextNotificationsReload
)
3507 v8::HandleScope
handleScope(v8::Isolate::GetCurrent());
3509 registerMockedHttpURLLoad("context_notifications_test.html");
3510 registerMockedHttpURLLoad("context_notifications_test_frame.html");
3512 ContextLifetimeTestWebFrameClient webFrameClient
;
3513 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3514 webViewHelper
.initializeAndLoad(m_baseURL
+ "context_notifications_test.html", true, &webFrameClient
);
3516 // Refresh, we should get two release notifications and two more create notifications.
3517 FrameTestHelpers::reloadFrame(webViewHelper
.webView()->mainFrame());
3518 ASSERT_EQ(4u, webFrameClient
.createNotifications
.size());
3519 ASSERT_EQ(2u, webFrameClient
.releaseNotifications
.size());
3521 // The two release notifications we got should be exactly the same as the first two create notifications.
3522 for (size_t i
= 0; i
< webFrameClient
.releaseNotifications
.size(); ++i
) {
3523 EXPECT_TRUE(webFrameClient
.releaseNotifications
[i
]->Equals(
3524 webFrameClient
.createNotifications
[webFrameClient
.createNotifications
.size() - 3 - i
]));
3527 // The last two create notifications should be for the current frames and context.
3528 WebFrame
* mainFrame
= webViewHelper
.webView()->mainFrame();
3529 WebFrame
* childFrame
= mainFrame
->firstChild();
3530 ContextLifetimeTestWebFrameClient::Notification
* firstRefreshNotification
= webFrameClient
.createNotifications
[2];
3531 ContextLifetimeTestWebFrameClient::Notification
* secondRefreshNotification
= webFrameClient
.createNotifications
[3];
3533 EXPECT_EQ(mainFrame
, firstRefreshNotification
->frame
);
3534 EXPECT_EQ(mainFrame
->mainWorldScriptContext(), firstRefreshNotification
->context
);
3535 EXPECT_EQ(0, firstRefreshNotification
->worldId
);
3537 EXPECT_EQ(childFrame
, secondRefreshNotification
->frame
);
3538 EXPECT_EQ(childFrame
->mainWorldScriptContext(), secondRefreshNotification
->context
);
3539 EXPECT_EQ(0, secondRefreshNotification
->worldId
);
3542 TEST_P(ParameterizedWebFrameTest
, ContextNotificationsIsolatedWorlds
)
3544 v8::Isolate
* isolate
= v8::Isolate::GetCurrent();
3545 v8::HandleScope
handleScope(isolate
);
3547 registerMockedHttpURLLoad("context_notifications_test.html");
3548 registerMockedHttpURLLoad("context_notifications_test_frame.html");
3550 ContextLifetimeTestWebFrameClient webFrameClient
;
3551 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3552 webViewHelper
.initializeAndLoad(m_baseURL
+ "context_notifications_test.html", true, &webFrameClient
);
3554 // Add an isolated world.
3555 webFrameClient
.reset();
3557 int isolatedWorldId
= 42;
3558 WebScriptSource
scriptSource("hi!");
3560 int extensionGroup
= 0;
3561 webViewHelper
.webView()->mainFrame()->executeScriptInIsolatedWorld(isolatedWorldId
, &scriptSource
, numSources
, extensionGroup
);
3563 // We should now have a new create notification.
3564 ASSERT_EQ(1u, webFrameClient
.createNotifications
.size());
3565 ContextLifetimeTestWebFrameClient::Notification
* notification
= webFrameClient
.createNotifications
[0];
3566 ASSERT_EQ(isolatedWorldId
, notification
->worldId
);
3567 ASSERT_EQ(webViewHelper
.webView()->mainFrame(), notification
->frame
);
3569 // We don't have an API to enumarate isolated worlds for a frame, but we can at least assert that the context we got is *not* the main world's context.
3570 ASSERT_NE(webViewHelper
.webView()->mainFrame()->mainWorldScriptContext(), v8::Local
<v8::Context
>::New(isolate
, notification
->context
));
3572 webViewHelper
.reset();
3574 // We should have gotten three release notifications (one for each of the frames, plus one for the isolated context).
3575 ASSERT_EQ(3u, webFrameClient
.releaseNotifications
.size());
3577 // And one of them should be exactly the same as the create notification for the isolated context.
3579 for (size_t i
= 0; i
< webFrameClient
.releaseNotifications
.size(); ++i
) {
3580 if (webFrameClient
.releaseNotifications
[i
]->Equals(webFrameClient
.createNotifications
[0]))
3583 EXPECT_EQ(1, matchCount
);
3586 TEST_P(ParameterizedWebFrameTest
, FindInPage
)
3588 registerMockedHttpURLLoad("find.html");
3589 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3590 webViewHelper
.initializeAndLoad(m_baseURL
+ "find.html");
3591 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
3592 const int findIdentifier
= 12345;
3593 WebFindOptions options
;
3595 // Find in a <div> element.
3596 EXPECT_TRUE(frame
->find(findIdentifier
, WebString::fromUTF8("bar1"), options
, false, 0));
3597 frame
->stopFinding(false);
3598 WebRange range
= frame
->selectionRange();
3599 EXPECT_EQ(5, range
.startOffset());
3600 EXPECT_EQ(9, range
.endOffset());
3601 EXPECT_TRUE(frame
->document().focusedElement().isNull());
3603 // Find in an <input> value.
3604 EXPECT_TRUE(frame
->find(findIdentifier
, WebString::fromUTF8("bar2"), options
, false, 0));
3605 // Confirm stopFinding(false) sets the selection on the found text.
3606 frame
->stopFinding(false);
3607 range
= frame
->selectionRange();
3608 ASSERT_FALSE(range
.isNull());
3609 EXPECT_EQ(5, range
.startOffset());
3610 EXPECT_EQ(9, range
.endOffset());
3611 EXPECT_TRUE(frame
->document().focusedElement().hasHTMLTagName("input"));
3613 // Find in a <textarea> content.
3614 EXPECT_TRUE(frame
->find(findIdentifier
, WebString::fromUTF8("bar3"), options
, false, 0));
3615 // Confirm stopFinding(false) sets the selection on the found text.
3616 frame
->stopFinding(false);
3617 range
= frame
->selectionRange();
3618 ASSERT_FALSE(range
.isNull());
3619 EXPECT_EQ(5, range
.startOffset());
3620 EXPECT_EQ(9, range
.endOffset());
3621 EXPECT_TRUE(frame
->document().focusedElement().hasHTMLTagName("textarea"));
3623 // Find in a contentEditable element.
3624 EXPECT_TRUE(frame
->find(findIdentifier
, WebString::fromUTF8("bar4"), options
, false, 0));
3625 // Confirm stopFinding(false) sets the selection on the found text.
3626 frame
->stopFinding(false);
3627 range
= frame
->selectionRange();
3628 ASSERT_FALSE(range
.isNull());
3629 EXPECT_EQ(0, range
.startOffset());
3630 EXPECT_EQ(4, range
.endOffset());
3631 // "bar4" is surrounded by <span>, but the focusable node should be the parent <div>.
3632 EXPECT_TRUE(frame
->document().focusedElement().hasHTMLTagName("div"));
3634 // Find in <select> content.
3635 EXPECT_FALSE(frame
->find(findIdentifier
, WebString::fromUTF8("bar5"), options
, false, 0));
3636 // If there are any matches, stopFinding will set the selection on the found text.
3637 // However, we do not expect any matches, so check that the selection is null.
3638 frame
->stopFinding(false);
3639 range
= frame
->selectionRange();
3640 ASSERT_TRUE(range
.isNull());
3643 TEST_P(ParameterizedWebFrameTest
, GetContentAsPlainText
)
3645 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3646 webViewHelper
.initializeAndLoad("about:blank", true);
3647 // We set the size because it impacts line wrapping, which changes the
3648 // resulting text value.
3649 webViewHelper
.webView()->resize(WebSize(640, 480));
3650 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
3652 // Generate a simple test case.
3653 const char simpleSource
[] = "<div>Foo bar</div><div></div>baz";
3654 KURL testURL
= toKURL("about:blank");
3655 FrameTestHelpers::loadHTMLString(frame
, simpleSource
, testURL
);
3657 // Make sure it comes out OK.
3658 const std::string
expected("Foo bar\nbaz");
3659 WebString text
= frame
->contentAsText(std::numeric_limits
<size_t>::max());
3660 EXPECT_EQ(expected
, text
.utf8());
3662 // Try reading the same one with clipping of the text.
3663 const int length
= 5;
3664 text
= frame
->contentAsText(length
);
3665 EXPECT_EQ(expected
.substr(0, length
), text
.utf8());
3667 // Now do a new test with a subframe.
3668 const char outerFrameSource
[] = "Hello<iframe></iframe> world";
3669 FrameTestHelpers::loadHTMLString(frame
, outerFrameSource
, testURL
);
3671 // Load something into the subframe.
3672 WebFrame
* subframe
= frame
->firstChild();
3673 ASSERT_TRUE(subframe
);
3674 FrameTestHelpers::loadHTMLString(subframe
, "sub<p>text", testURL
);
3676 text
= frame
->contentAsText(std::numeric_limits
<size_t>::max());
3677 EXPECT_EQ("Hello world\n\nsub\ntext", text
.utf8());
3679 // Get the frame text where the subframe separator falls on the boundary of
3680 // what we'll take. There used to be a crash in this case.
3681 text
= frame
->contentAsText(12);
3682 EXPECT_EQ("Hello world", text
.utf8());
3685 TEST_P(ParameterizedWebFrameTest
, GetFullHtmlOfPage
)
3687 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3688 webViewHelper
.initializeAndLoad("about:blank", true);
3689 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
3691 // Generate a simple test case.
3692 const char simpleSource
[] = "<p>Hello</p><p>World</p>";
3693 KURL testURL
= toKURL("about:blank");
3694 FrameTestHelpers::loadHTMLString(frame
, simpleSource
, testURL
);
3696 WebString text
= frame
->contentAsText(std::numeric_limits
<size_t>::max());
3697 EXPECT_EQ("Hello\n\nWorld", text
.utf8());
3699 const std::string html
= frame
->contentAsMarkup().utf8();
3701 // Load again with the output html.
3702 FrameTestHelpers::loadHTMLString(frame
, html
, testURL
);
3704 EXPECT_EQ(html
, frame
->contentAsMarkup().utf8());
3706 text
= frame
->contentAsText(std::numeric_limits
<size_t>::max());
3707 EXPECT_EQ("Hello\n\nWorld", text
.utf8());
3709 // Test selection check
3710 EXPECT_FALSE(frame
->hasSelection());
3711 frame
->executeCommand(WebString::fromUTF8("SelectAll"));
3712 EXPECT_TRUE(frame
->hasSelection());
3713 frame
->executeCommand(WebString::fromUTF8("Unselect"));
3714 EXPECT_FALSE(frame
->hasSelection());
3715 WebString selectionHtml
= frame
->selectionAsMarkup();
3716 EXPECT_TRUE(selectionHtml
.isEmpty());
3719 class TestExecuteScriptDuringDidCreateScriptContext
: public FrameTestHelpers::TestWebFrameClient
{
3721 void didCreateScriptContext(WebLocalFrame
* frame
, v8::Local
<v8::Context
> context
, int extensionGroup
, int worldId
) override
3723 frame
->executeScript(WebScriptSource("window.history = 'replaced';"));
3727 TEST_P(ParameterizedWebFrameTest
, ExecuteScriptDuringDidCreateScriptContext
)
3729 registerMockedHttpURLLoad("hello_world.html");
3731 TestExecuteScriptDuringDidCreateScriptContext webFrameClient
;
3732 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3733 webViewHelper
.initializeAndLoad(m_baseURL
+ "hello_world.html", true, &webFrameClient
);
3735 FrameTestHelpers::reloadFrame(webViewHelper
.webView()->mainFrame());
3738 class FindUpdateWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
3740 FindUpdateWebFrameClient()
3741 : m_findResultsAreReady(false)
3746 void reportFindInPageMatchCount(int, int count
, bool finalUpdate
) override
3750 m_findResultsAreReady
= true;
3753 bool findResultsAreReady() const { return m_findResultsAreReady
; }
3754 int count() const { return m_count
; }
3757 bool m_findResultsAreReady
;
3761 TEST_P(ParameterizedWebFrameTest
, FindInPageMatchRects
)
3763 registerMockedHttpURLLoad("find_in_page.html");
3764 registerMockedHttpURLLoad("find_in_page_frame.html");
3766 FindUpdateWebFrameClient client
;
3767 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3768 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_page.html", true, &client
);
3769 webViewHelper
.webView()->resize(WebSize(640, 480));
3770 webViewHelper
.webView()->setMaximumLegibleScale(1.f
);
3771 webViewHelper
.webView()->layout();
3774 // Note that the 'result 19' in the <select> element is not expected to produce a match.
3775 static const char* kFindString
= "result";
3776 static const int kFindIdentifier
= 12345;
3777 static const int kNumResults
= 19;
3779 WebFindOptions options
;
3780 WebString searchText
= WebString::fromUTF8(kFindString
);
3781 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
3782 EXPECT_TRUE(mainFrame
->find(kFindIdentifier
, searchText
, options
, false, 0));
3784 mainFrame
->resetMatchCount();
3786 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
3787 frame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
3790 EXPECT_TRUE(client
.findResultsAreReady());
3792 WebVector
<WebFloatRect
> webMatchRects
;
3793 mainFrame
->findMatchRects(webMatchRects
);
3794 ASSERT_EQ(webMatchRects
.size(), static_cast<size_t>(kNumResults
));
3795 int rectsVersion
= mainFrame
->findMatchMarkersVersion();
3797 for (int resultIndex
= 0; resultIndex
< kNumResults
; ++resultIndex
) {
3798 FloatRect resultRect
= static_cast<FloatRect
>(webMatchRects
[resultIndex
]);
3800 // Select the match by the center of its rect.
3801 EXPECT_EQ(mainFrame
->selectNearestFindMatch(resultRect
.center(), 0), resultIndex
+ 1);
3803 // Check that the find result ordering matches with our expectations.
3804 Range
* result
= mainFrame
->activeMatchFrame()->activeMatch();
3805 ASSERT_TRUE(result
);
3806 result
->setEnd(result
->endContainer(), result
->endOffset() + 3);
3807 EXPECT_EQ(result
->text(), String::format("%s %02d", kFindString
, resultIndex
));
3809 // Verify that the expected match rect also matches the currently active match.
3810 // Compare the enclosing rects to prevent precision issues caused by CSS transforms.
3811 FloatRect activeMatch
= mainFrame
->activeFindMatchRect();
3812 EXPECT_EQ(enclosingIntRect(activeMatch
), enclosingIntRect(resultRect
));
3814 // The rects version should not have changed.
3815 EXPECT_EQ(mainFrame
->findMatchMarkersVersion(), rectsVersion
);
3818 // All results after the first two ones should be below between them in find-in-page coordinates.
3819 // This is because results 2 to 9 are inside an iframe located between results 0 and 1. This applies to the fixed div too.
3820 EXPECT_TRUE(webMatchRects
[0].y
< webMatchRects
[1].y
);
3821 for (int resultIndex
= 2; resultIndex
< kNumResults
; ++resultIndex
) {
3822 EXPECT_TRUE(webMatchRects
[0].y
< webMatchRects
[resultIndex
].y
);
3823 EXPECT_TRUE(webMatchRects
[1].y
> webMatchRects
[resultIndex
].y
);
3826 // Result 3 should be below both 2 and 4. This is caused by the CSS transform in the containing div.
3827 // If the transform doesn't work then 3 will be between 2 and 4.
3828 EXPECT_TRUE(webMatchRects
[3].y
> webMatchRects
[2].y
);
3829 EXPECT_TRUE(webMatchRects
[3].y
> webMatchRects
[4].y
);
3831 // Results 6, 7, 8 and 9 should be one below the other in that same order.
3832 // If overflow:scroll is not properly handled then result 8 would be below result 9 or
3833 // result 7 above result 6 depending on the scroll.
3834 EXPECT_TRUE(webMatchRects
[6].y
< webMatchRects
[7].y
);
3835 EXPECT_TRUE(webMatchRects
[7].y
< webMatchRects
[8].y
);
3836 EXPECT_TRUE(webMatchRects
[8].y
< webMatchRects
[9].y
);
3838 // Results 11, 12, 13 and 14 should be between results 10 and 15, as they are inside the table.
3839 EXPECT_TRUE(webMatchRects
[11].y
> webMatchRects
[10].y
);
3840 EXPECT_TRUE(webMatchRects
[12].y
> webMatchRects
[10].y
);
3841 EXPECT_TRUE(webMatchRects
[13].y
> webMatchRects
[10].y
);
3842 EXPECT_TRUE(webMatchRects
[14].y
> webMatchRects
[10].y
);
3843 EXPECT_TRUE(webMatchRects
[11].y
< webMatchRects
[15].y
);
3844 EXPECT_TRUE(webMatchRects
[12].y
< webMatchRects
[15].y
);
3845 EXPECT_TRUE(webMatchRects
[13].y
< webMatchRects
[15].y
);
3846 EXPECT_TRUE(webMatchRects
[14].y
< webMatchRects
[15].y
);
3848 // Result 11 should be above 12, 13 and 14 as it's in the table header.
3849 EXPECT_TRUE(webMatchRects
[11].y
< webMatchRects
[12].y
);
3850 EXPECT_TRUE(webMatchRects
[11].y
< webMatchRects
[13].y
);
3851 EXPECT_TRUE(webMatchRects
[11].y
< webMatchRects
[14].y
);
3853 // Result 11 should also be right to 12, 13 and 14 because of the colspan.
3854 EXPECT_TRUE(webMatchRects
[11].x
> webMatchRects
[12].x
);
3855 EXPECT_TRUE(webMatchRects
[11].x
> webMatchRects
[13].x
);
3856 EXPECT_TRUE(webMatchRects
[11].x
> webMatchRects
[14].x
);
3858 // Result 12 should be left to results 11, 13 and 14 in the table layout.
3859 EXPECT_TRUE(webMatchRects
[12].x
< webMatchRects
[11].x
);
3860 EXPECT_TRUE(webMatchRects
[12].x
< webMatchRects
[13].x
);
3861 EXPECT_TRUE(webMatchRects
[12].x
< webMatchRects
[14].x
);
3863 // Results 13, 12 and 14 should be one above the other in that order because of the rowspan
3864 // and vertical-align: middle by default.
3865 EXPECT_TRUE(webMatchRects
[13].y
< webMatchRects
[12].y
);
3866 EXPECT_TRUE(webMatchRects
[12].y
< webMatchRects
[14].y
);
3868 // Result 16 should be below result 15.
3869 EXPECT_TRUE(webMatchRects
[15].y
> webMatchRects
[14].y
);
3871 // Result 18 should be normalized with respect to the position:relative div, and not it's
3872 // immediate containing div. Consequently, result 18 should be above result 17.
3873 EXPECT_TRUE(webMatchRects
[17].y
> webMatchRects
[18].y
);
3875 // Resizing should update the rects version.
3876 webViewHelper
.webView()->resize(WebSize(800, 600));
3877 webViewHelper
.webView()->layout();
3879 EXPECT_TRUE(mainFrame
->findMatchMarkersVersion() != rectsVersion
);
3882 TEST_P(ParameterizedWebFrameTest
, FindInPageSkipsHiddenFrames
)
3884 registerMockedHttpURLLoad("find_in_hidden_frame.html");
3886 FindUpdateWebFrameClient client
;
3887 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3888 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_hidden_frame.html", true, &client
);
3889 webViewHelper
.webView()->resize(WebSize(640, 480));
3890 webViewHelper
.webView()->layout();
3893 static const char* kFindString
= "hello";
3894 static const int kFindIdentifier
= 12345;
3895 static const int kNumResults
= 1;
3897 WebFindOptions options
;
3898 WebString searchText
= WebString::fromUTF8(kFindString
);
3899 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
3900 EXPECT_TRUE(mainFrame
->find(kFindIdentifier
, searchText
, options
, false, 0));
3902 mainFrame
->resetMatchCount();
3904 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
3905 frame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
3908 EXPECT_TRUE(client
.findResultsAreReady());
3909 EXPECT_EQ(kNumResults
, client
.count());
3912 TEST_P(ParameterizedWebFrameTest
, FindOnDetachedFrame
)
3914 registerMockedHttpURLLoad("find_in_page.html");
3915 registerMockedHttpURLLoad("find_in_page_frame.html");
3917 FindUpdateWebFrameClient client
;
3918 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3919 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_page.html", true, &client
);
3920 webViewHelper
.webView()->resize(WebSize(640, 480));
3921 webViewHelper
.webView()->layout();
3924 static const char* kFindString
= "result";
3925 static const int kFindIdentifier
= 12345;
3927 WebFindOptions options
;
3928 WebString searchText
= WebString::fromUTF8(kFindString
);
3929 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
3930 RefPtrWillBeRawPtr
<WebLocalFrameImpl
> secondFrame
= toWebLocalFrameImpl(mainFrame
->traverseNext(false));
3931 RefPtrWillBeRawPtr
<LocalFrame
> holdSecondFrame(secondFrame
->frame());
3933 // Detach the frame before finding.
3934 removeElementById(mainFrame
, "frame");
3936 EXPECT_TRUE(mainFrame
->find(kFindIdentifier
, searchText
, options
, false, 0));
3937 EXPECT_FALSE(secondFrame
->find(kFindIdentifier
, searchText
, options
, false, 0));
3940 EXPECT_FALSE(client
.findResultsAreReady());
3942 mainFrame
->resetMatchCount();
3944 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
3945 frame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
3948 EXPECT_TRUE(client
.findResultsAreReady());
3951 TEST_P(ParameterizedWebFrameTest
, FindDetachFrameBeforeScopeStrings
)
3953 registerMockedHttpURLLoad("find_in_page.html");
3954 registerMockedHttpURLLoad("find_in_page_frame.html");
3956 FindUpdateWebFrameClient client
;
3957 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3958 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_page.html", true, &client
);
3959 webViewHelper
.webView()->resize(WebSize(640, 480));
3960 webViewHelper
.webView()->layout();
3963 static const char* kFindString
= "result";
3964 static const int kFindIdentifier
= 12345;
3966 WebFindOptions options
;
3967 WebString searchText
= WebString::fromUTF8(kFindString
);
3968 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
3969 WebLocalFrameImpl
* secondFrame
= toWebLocalFrameImpl(mainFrame
->traverseNext(false));
3970 RefPtrWillBeRawPtr
<LocalFrame
> holdSecondFrame(secondFrame
->frame());
3972 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
3973 EXPECT_TRUE(frame
->find(kFindIdentifier
, searchText
, options
, false, 0));
3976 EXPECT_FALSE(client
.findResultsAreReady());
3978 // Detach the frame between finding and scoping.
3979 removeElementById(mainFrame
, "frame");
3981 mainFrame
->resetMatchCount();
3983 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
3984 frame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
3987 EXPECT_TRUE(client
.findResultsAreReady());
3990 TEST_P(ParameterizedWebFrameTest
, FindDetachFrameWhileScopingStrings
)
3992 registerMockedHttpURLLoad("find_in_page.html");
3993 registerMockedHttpURLLoad("find_in_page_frame.html");
3995 FindUpdateWebFrameClient client
;
3996 FrameTestHelpers::WebViewHelper
webViewHelper(this);
3997 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_page.html", true, &client
);
3998 webViewHelper
.webView()->resize(WebSize(640, 480));
3999 webViewHelper
.webView()->layout();
4002 static const char* kFindString
= "result";
4003 static const int kFindIdentifier
= 12345;
4005 WebFindOptions options
;
4006 WebString searchText
= WebString::fromUTF8(kFindString
);
4007 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4008 WebLocalFrameImpl
* secondFrame
= toWebLocalFrameImpl(mainFrame
->traverseNext(false));
4009 RefPtrWillBeRawPtr
<LocalFrame
> holdSecondFrame(secondFrame
->frame());
4011 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
4012 EXPECT_TRUE(frame
->find(kFindIdentifier
, searchText
, options
, false, 0));
4015 EXPECT_FALSE(client
.findResultsAreReady());
4017 mainFrame
->resetMatchCount();
4019 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false))
4020 frame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
4022 // The first scopeStringMatches will have reset the state. Detach before it actually scopes.
4023 removeElementById(mainFrame
, "frame");
4026 EXPECT_TRUE(client
.findResultsAreReady());
4029 TEST_P(ParameterizedWebFrameTest
, ResetMatchCount
)
4031 registerMockedHttpURLLoad("find_in_generated_frame.html");
4033 FindUpdateWebFrameClient client
;
4034 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4035 webViewHelper
.initializeAndLoad(m_baseURL
+ "find_in_generated_frame.html", true, &client
);
4036 webViewHelper
.webView()->resize(WebSize(640, 480));
4037 webViewHelper
.webView()->layout();
4040 static const char* kFindString
= "result";
4041 static const int kFindIdentifier
= 12345;
4043 WebFindOptions options
;
4044 WebString searchText
= WebString::fromUTF8(kFindString
);
4045 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4047 // Check that child frame exists.
4048 EXPECT_TRUE(!!mainFrame
->traverseNext(false));
4050 for (WebFrame
* frame
= mainFrame
; frame
; frame
= frame
->traverseNext(false)) {
4051 EXPECT_FALSE(frame
->find(kFindIdentifier
, searchText
, options
, false, 0));
4055 EXPECT_FALSE(client
.findResultsAreReady());
4057 mainFrame
->resetMatchCount();
4060 TEST_P(ParameterizedWebFrameTest
, SetTickmarks
)
4062 registerMockedHttpURLLoad("find.html");
4064 FindUpdateWebFrameClient client
;
4065 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4066 webViewHelper
.initializeAndLoad(m_baseURL
+ "find.html", true, &client
);
4067 webViewHelper
.webView()->resize(WebSize(640, 480));
4068 webViewHelper
.webView()->layout();
4071 static const char* kFindString
= "foo";
4072 static const int kFindIdentifier
= 12345;
4074 WebFindOptions options
;
4075 WebString searchText
= WebString::fromUTF8(kFindString
);
4076 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4077 EXPECT_TRUE(mainFrame
->find(kFindIdentifier
, searchText
, options
, false, 0));
4079 mainFrame
->resetMatchCount();
4080 mainFrame
->scopeStringMatches(kFindIdentifier
, searchText
, options
, true);
4083 EXPECT_TRUE(client
.findResultsAreReady());
4085 // Get the tickmarks for the original find request.
4086 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
4087 RefPtrWillBeRawPtr
<Scrollbar
> scrollbar
= frameView
->createScrollbar(HorizontalScrollbar
);
4088 Vector
<IntRect
> originalTickmarks
;
4089 scrollbar
->getTickmarks(originalTickmarks
);
4090 EXPECT_EQ(4u, originalTickmarks
.size());
4092 // Override the tickmarks.
4093 Vector
<IntRect
> overridingTickmarksExpected
;
4094 overridingTickmarksExpected
.append(IntRect(0, 0, 100, 100));
4095 overridingTickmarksExpected
.append(IntRect(0, 20, 100, 100));
4096 overridingTickmarksExpected
.append(IntRect(0, 30, 100, 100));
4097 mainFrame
->setTickmarks(overridingTickmarksExpected
);
4099 // Check the tickmarks are overriden correctly.
4100 Vector
<IntRect
> overridingTickmarksActual
;
4101 scrollbar
->getTickmarks(overridingTickmarksActual
);
4102 EXPECT_EQ(overridingTickmarksExpected
, overridingTickmarksActual
);
4104 // Reset the tickmark behavior.
4105 Vector
<IntRect
> resetTickmarks
;
4106 mainFrame
->setTickmarks(resetTickmarks
);
4108 // Check that the original tickmarks are returned
4109 Vector
<IntRect
> originalTickmarksAfterReset
;
4110 scrollbar
->getTickmarks(originalTickmarksAfterReset
);
4111 EXPECT_EQ(originalTickmarks
, originalTickmarksAfterReset
);
4114 static WebPoint
topLeft(const WebRect
& rect
)
4116 return WebPoint(rect
.x
, rect
.y
);
4119 static WebPoint
bottomRightMinusOne(const WebRect
& rect
)
4121 // FIXME: If we don't subtract 1 from the x- and y-coordinates of the
4122 // selection bounds, selectRange() will select the *next* element. That's
4123 // strictly correct, as hit-testing checks the pixel to the lower-right of
4124 // the input coordinate, but it's a wart on the API.
4125 return WebPoint(rect
.x
+ rect
.width
- 1, rect
.y
+ rect
.height
- 1);
4128 static WebRect
elementBounds(WebFrame
* frame
, const WebString
& id
)
4130 return frame
->document().getElementById(id
).boundsInViewportSpace();
4133 static std::string
selectionAsString(WebFrame
* frame
)
4135 return frame
->selectionAsText().utf8();
4138 TEST_P(ParameterizedWebFrameTest
, SelectRange
)
4141 WebRect startWebRect
;
4144 registerMockedHttpURLLoad("select_range_basic.html");
4145 registerMockedHttpURLLoad("select_range_scroll.html");
4147 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4148 initializeTextSelectionWebView(m_baseURL
+ "select_range_basic.html", &webViewHelper
);
4149 frame
= webViewHelper
.webView()->mainFrame();
4150 EXPECT_EQ("Some test text for testing.", selectionAsString(frame
));
4151 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4152 frame
->executeCommand(WebString::fromUTF8("Unselect"));
4153 EXPECT_EQ("", selectionAsString(frame
));
4154 frame
->selectRange(topLeft(startWebRect
), bottomRightMinusOne(endWebRect
));
4155 EXPECT_EQ("Some test text for testing.", selectionAsString(frame
));
4157 initializeTextSelectionWebView(m_baseURL
+ "select_range_scroll.html", &webViewHelper
);
4158 frame
= webViewHelper
.webView()->mainFrame();
4159 EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame
));
4160 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4161 frame
->executeCommand(WebString::fromUTF8("Unselect"));
4162 EXPECT_EQ("", selectionAsString(frame
));
4163 frame
->selectRange(topLeft(startWebRect
), bottomRightMinusOne(endWebRect
));
4164 EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame
));
4167 TEST_P(ParameterizedWebFrameTest
, SelectRangeInIframe
)
4170 WebRect startWebRect
;
4173 registerMockedHttpURLLoad("select_range_iframe.html");
4174 registerMockedHttpURLLoad("select_range_basic.html");
4176 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4177 initializeTextSelectionWebView(m_baseURL
+ "select_range_iframe.html", &webViewHelper
);
4178 frame
= webViewHelper
.webView()->mainFrame();
4179 WebFrame
* subframe
= frame
->firstChild();
4180 EXPECT_EQ("Some test text for testing.", selectionAsString(subframe
));
4181 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4182 subframe
->executeCommand(WebString::fromUTF8("Unselect"));
4183 EXPECT_EQ("", selectionAsString(subframe
));
4184 subframe
->selectRange(topLeft(startWebRect
), bottomRightMinusOne(endWebRect
));
4185 EXPECT_EQ("Some test text for testing.", selectionAsString(subframe
));
4188 TEST_P(ParameterizedWebFrameTest
, SelectRangeDivContentEditable
)
4191 WebRect startWebRect
;
4194 registerMockedHttpURLLoad("select_range_div_editable.html");
4196 // Select the middle of an editable element, then try to extend the selection to the top of the document.
4197 // The selection range should be clipped to the bounds of the editable element.
4198 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4199 initializeTextSelectionWebView(m_baseURL
+ "select_range_div_editable.html", &webViewHelper
);
4200 frame
= webViewHelper
.webView()->mainFrame();
4201 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4202 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4204 frame
->selectRange(bottomRightMinusOne(endWebRect
), WebPoint(0, 0));
4205 EXPECT_EQ("16-char header. This text is initially selected.", selectionAsString(frame
));
4207 // As above, but extending the selection to the bottom of the document.
4208 initializeTextSelectionWebView(m_baseURL
+ "select_range_div_editable.html", &webViewHelper
);
4209 frame
= webViewHelper
.webView()->mainFrame();
4211 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4212 frame
->selectRange(topLeft(startWebRect
), bottomRightMinusOne(endWebRect
));
4213 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4214 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4216 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4217 frame
->selectRange(topLeft(startWebRect
), WebPoint(640, 480));
4218 EXPECT_EQ("This text is initially selected. 16-char footer.", selectionAsString(frame
));
4221 // positionForPoint returns the wrong values for contenteditable spans. See
4222 // http://crbug.com/238334.
4223 TEST_P(ParameterizedWebFrameTest
, DISABLED_SelectRangeSpanContentEditable
)
4226 WebRect startWebRect
;
4229 registerMockedHttpURLLoad("select_range_span_editable.html");
4231 // Select the middle of an editable element, then try to extend the selection to the top of the document.
4232 // The selection range should be clipped to the bounds of the editable element.
4233 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4234 initializeTextSelectionWebView(m_baseURL
+ "select_range_span_editable.html", &webViewHelper
);
4235 frame
= webViewHelper
.webView()->mainFrame();
4236 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4237 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4239 frame
->selectRange(bottomRightMinusOne(endWebRect
), WebPoint(0, 0));
4240 EXPECT_EQ("16-char header. This text is initially selected.", selectionAsString(frame
));
4242 // As above, but extending the selection to the bottom of the document.
4243 initializeTextSelectionWebView(m_baseURL
+ "select_range_span_editable.html", &webViewHelper
);
4244 frame
= webViewHelper
.webView()->mainFrame();
4246 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4247 frame
->selectRange(topLeft(startWebRect
), bottomRightMinusOne(endWebRect
));
4248 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4249 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4251 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4252 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4253 frame
->selectRange(topLeft(startWebRect
), WebPoint(640, 480));
4254 EXPECT_EQ("This text is initially selected. 16-char footer.", selectionAsString(frame
));
4257 TEST_P(ParameterizedWebFrameTest
, SelectRangeCanMoveSelectionStart
)
4259 registerMockedHttpURLLoad("text_selection.html");
4260 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4261 initializeTextSelectionWebView(m_baseURL
+ "text_selection.html", &webViewHelper
);
4262 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
4264 // Select second span. We can move the start to include the first span.
4265 frame
->executeScript(WebScriptSource("selectElement('header_2');"));
4266 EXPECT_EQ("Header 2.", selectionAsString(frame
));
4267 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "header_2")), topLeft(elementBounds(frame
, "header_1")));
4268 EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame
));
4270 // We can move the start and end together.
4271 frame
->executeScript(WebScriptSource("selectElement('header_1');"));
4272 EXPECT_EQ("Header 1.", selectionAsString(frame
));
4273 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "header_1")), bottomRightMinusOne(elementBounds(frame
, "header_1")));
4274 EXPECT_EQ("", selectionAsString(frame
));
4275 // Selection is a caret, not empty.
4276 EXPECT_FALSE(frame
->selectionRange().isNull());
4278 // We can move the start across the end.
4279 frame
->executeScript(WebScriptSource("selectElement('header_1');"));
4280 EXPECT_EQ("Header 1.", selectionAsString(frame
));
4281 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "header_1")), bottomRightMinusOne(elementBounds(frame
, "header_2")));
4282 EXPECT_EQ(" Header 2.", selectionAsString(frame
));
4284 // Can't extend the selection part-way into an editable element.
4285 frame
->executeScript(WebScriptSource("selectElement('footer_2');"));
4286 EXPECT_EQ("Footer 2.", selectionAsString(frame
));
4287 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "footer_2")), topLeft(elementBounds(frame
, "editable_2")));
4288 EXPECT_EQ(" [ Footer 1. Footer 2.", selectionAsString(frame
));
4290 // Can extend the selection completely across editable elements.
4291 frame
->executeScript(WebScriptSource("selectElement('footer_2');"));
4292 EXPECT_EQ("Footer 2.", selectionAsString(frame
));
4293 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "footer_2")), topLeft(elementBounds(frame
, "header_2")));
4294 EXPECT_EQ("Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1. Footer 2.", selectionAsString(frame
));
4296 // If the selection is editable text, we can't extend it into non-editable text.
4297 frame
->executeScript(WebScriptSource("selectElement('editable_2');"));
4298 EXPECT_EQ("Editable 2.", selectionAsString(frame
));
4299 frame
->selectRange(bottomRightMinusOne(elementBounds(frame
, "editable_2")), topLeft(elementBounds(frame
, "header_2")));
4300 // positionForPoint returns the wrong values for contenteditable spans. See
4301 // http://crbug.com/238334.
4302 // EXPECT_EQ("[ Editable 1. Editable 2.", selectionAsString(frame));
4305 TEST_P(ParameterizedWebFrameTest
, SelectRangeCanMoveSelectionEnd
)
4307 registerMockedHttpURLLoad("text_selection.html");
4308 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4309 initializeTextSelectionWebView(m_baseURL
+ "text_selection.html", &webViewHelper
);
4310 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
4312 // Select first span. We can move the end to include the second span.
4313 frame
->executeScript(WebScriptSource("selectElement('header_1');"));
4314 EXPECT_EQ("Header 1.", selectionAsString(frame
));
4315 frame
->selectRange(topLeft(elementBounds(frame
, "header_1")), bottomRightMinusOne(elementBounds(frame
, "header_2")));
4316 EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame
));
4318 // We can move the start and end together.
4319 frame
->executeScript(WebScriptSource("selectElement('header_2');"));
4320 EXPECT_EQ("Header 2.", selectionAsString(frame
));
4321 frame
->selectRange(topLeft(elementBounds(frame
, "header_2")), topLeft(elementBounds(frame
, "header_2")));
4322 EXPECT_EQ("", selectionAsString(frame
));
4323 // Selection is a caret, not empty.
4324 EXPECT_FALSE(frame
->selectionRange().isNull());
4326 // We can move the end across the start.
4327 frame
->executeScript(WebScriptSource("selectElement('header_2');"));
4328 EXPECT_EQ("Header 2.", selectionAsString(frame
));
4329 frame
->selectRange(topLeft(elementBounds(frame
, "header_2")), topLeft(elementBounds(frame
, "header_1")));
4330 EXPECT_EQ("Header 1. ", selectionAsString(frame
));
4332 // Can't extend the selection part-way into an editable element.
4333 frame
->executeScript(WebScriptSource("selectElement('header_1');"));
4334 EXPECT_EQ("Header 1.", selectionAsString(frame
));
4335 frame
->selectRange(topLeft(elementBounds(frame
, "header_1")), bottomRightMinusOne(elementBounds(frame
, "editable_1")));
4336 EXPECT_EQ("Header 1. Header 2. ] ", selectionAsString(frame
));
4338 // Can extend the selection completely across editable elements.
4339 frame
->executeScript(WebScriptSource("selectElement('header_1');"));
4340 EXPECT_EQ("Header 1.", selectionAsString(frame
));
4341 frame
->selectRange(topLeft(elementBounds(frame
, "header_1")), bottomRightMinusOne(elementBounds(frame
, "footer_1")));
4342 EXPECT_EQ("Header 1. Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1.", selectionAsString(frame
));
4344 // If the selection is editable text, we can't extend it into non-editable text.
4345 frame
->executeScript(WebScriptSource("selectElement('editable_1');"));
4346 EXPECT_EQ("Editable 1.", selectionAsString(frame
));
4347 frame
->selectRange(topLeft(elementBounds(frame
, "editable_1")), bottomRightMinusOne(elementBounds(frame
, "footer_1")));
4348 // positionForPoint returns the wrong values for contenteditable spans. See
4349 // http://crbug.com/238334.
4350 // EXPECT_EQ("Editable 1. Editable 2. ]", selectionAsString(frame));
4353 TEST_P(ParameterizedWebFrameTest
, MoveRangeSelectionExtent
)
4355 WebLocalFrameImpl
* frame
;
4356 WebRect startWebRect
;
4359 registerMockedHttpURLLoad("move_range_selection_extent.html");
4361 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4362 initializeTextSelectionWebView(m_baseURL
+ "move_range_selection_extent.html", &webViewHelper
);
4363 frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4364 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4365 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4367 frame
->moveRangeSelectionExtent(WebPoint(640, 480));
4368 EXPECT_EQ("This text is initially selected. 16-char footer.", selectionAsString(frame
));
4370 frame
->moveRangeSelectionExtent(WebPoint(0, 0));
4371 EXPECT_EQ("16-char header. ", selectionAsString(frame
));
4373 // Reset with swapped base and extent.
4374 frame
->selectRange(topLeft(endWebRect
), bottomRightMinusOne(startWebRect
));
4375 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4377 frame
->moveRangeSelectionExtent(WebPoint(640, 480));
4378 EXPECT_EQ(" 16-char footer.", selectionAsString(frame
));
4380 frame
->moveRangeSelectionExtent(WebPoint(0, 0));
4381 EXPECT_EQ("16-char header. This text is initially selected.", selectionAsString(frame
));
4383 frame
->executeCommand(WebString::fromUTF8("Unselect"));
4384 EXPECT_EQ("", selectionAsString(frame
));
4387 TEST_P(ParameterizedWebFrameTest
, MoveRangeSelectionExtentCannotCollapse
)
4389 WebLocalFrameImpl
* frame
;
4390 WebRect startWebRect
;
4393 registerMockedHttpURLLoad("move_range_selection_extent.html");
4395 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4396 initializeTextSelectionWebView(m_baseURL
+ "move_range_selection_extent.html", &webViewHelper
);
4397 frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4398 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4399 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4401 frame
->moveRangeSelectionExtent(bottomRightMinusOne(startWebRect
));
4402 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4404 // Reset with swapped base and extent.
4405 frame
->selectRange(topLeft(endWebRect
), bottomRightMinusOne(startWebRect
));
4406 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4408 frame
->moveRangeSelectionExtent(bottomRightMinusOne(endWebRect
));
4409 EXPECT_EQ("This text is initially selected.", selectionAsString(frame
));
4412 TEST_P(ParameterizedWebFrameTest
, MoveRangeSelectionExtentScollsInputField
)
4414 WebLocalFrameImpl
* frame
;
4415 WebRect startWebRect
;
4418 registerMockedHttpURLLoad("move_range_selection_extent_input_field.html");
4420 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4421 initializeTextSelectionWebView(m_baseURL
+ "move_range_selection_extent_input_field.html", &webViewHelper
);
4422 frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4423 EXPECT_EQ("Length", selectionAsString(frame
));
4424 webViewHelper
.webView()->selectionBounds(startWebRect
, endWebRect
);
4426 EXPECT_EQ(0, frame
->frame()->selection().rootEditableElement()->scrollLeft());
4427 frame
->moveRangeSelectionExtent(WebPoint(endWebRect
.x
+ 500, endWebRect
.y
));
4428 EXPECT_GE(frame
->frame()->selection().rootEditableElement()->scrollLeft(), 1);
4429 EXPECT_EQ("Lengthy text goes here.", selectionAsString(frame
));
4432 static int computeOffset(LayoutObject
* layoutObject
, int x
, int y
)
4434 return createVisiblePosition(layoutObject
->positionForPoint(LayoutPoint(x
, y
))).deepEquivalent().computeOffsetInContainerNode();
4437 // positionForPoint returns the wrong values for contenteditable spans. See
4438 // http://crbug.com/238334.
4439 TEST_P(ParameterizedWebFrameTest
, DISABLED_PositionForPointTest
)
4441 registerMockedHttpURLLoad("select_range_span_editable.html");
4442 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4443 initializeTextSelectionWebView(m_baseURL
+ "select_range_span_editable.html", &webViewHelper
);
4444 WebLocalFrameImpl
* mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4445 LayoutObject
* layoutObject
= mainFrame
->frame()->selection().rootEditableElement()->layoutObject();
4446 EXPECT_EQ(0, computeOffset(layoutObject
, -1, -1));
4447 EXPECT_EQ(64, computeOffset(layoutObject
, 1000, 1000));
4449 registerMockedHttpURLLoad("select_range_div_editable.html");
4450 initializeTextSelectionWebView(m_baseURL
+ "select_range_div_editable.html", &webViewHelper
);
4451 mainFrame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4452 layoutObject
= mainFrame
->frame()->selection().rootEditableElement()->layoutObject();
4453 EXPECT_EQ(0, computeOffset(layoutObject
, -1, -1));
4454 EXPECT_EQ(64, computeOffset(layoutObject
, 1000, 1000));
4457 #if !OS(MACOSX) && !OS(LINUX)
4458 TEST_P(ParameterizedWebFrameTest
, SelectRangeStaysHorizontallyAlignedWhenMoved
)
4460 registerMockedHttpURLLoad("move_caret.html");
4462 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4463 initializeTextSelectionWebView(m_baseURL
+ "move_caret.html", &webViewHelper
);
4464 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
4466 WebRect initialStartRect
;
4467 WebRect initialEndRect
;
4471 frame
->executeScript(WebScriptSource("selectRange();"));
4472 webViewHelper
.webView()->selectionBounds(initialStartRect
, initialEndRect
);
4473 WebPoint
movedStart(topLeft(initialStartRect
));
4476 frame
->selectRange(movedStart
, bottomRightMinusOne(initialEndRect
));
4477 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4478 EXPECT_EQ(startRect
, initialStartRect
);
4479 EXPECT_EQ(endRect
, initialEndRect
);
4482 frame
->selectRange(movedStart
, bottomRightMinusOne(initialEndRect
));
4483 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4484 EXPECT_EQ(startRect
, initialStartRect
);
4485 EXPECT_EQ(endRect
, initialEndRect
);
4487 WebPoint
movedEnd(bottomRightMinusOne(initialEndRect
));
4490 frame
->selectRange(topLeft(initialStartRect
), movedEnd
);
4491 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4492 EXPECT_EQ(startRect
, initialStartRect
);
4493 EXPECT_EQ(endRect
, initialEndRect
);
4496 frame
->selectRange(topLeft(initialStartRect
), movedEnd
);
4497 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4498 EXPECT_EQ(startRect
, initialStartRect
);
4499 EXPECT_EQ(endRect
, initialEndRect
);
4502 TEST_P(ParameterizedWebFrameTest
, MoveCaretStaysHorizontallyAlignedWhenMoved
)
4504 WebLocalFrameImpl
* frame
;
4505 registerMockedHttpURLLoad("move_caret.html");
4507 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4508 initializeTextSelectionWebView(m_baseURL
+ "move_caret.html", &webViewHelper
);
4509 frame
= (WebLocalFrameImpl
*)webViewHelper
.webView()->mainFrame();
4511 WebRect initialStartRect
;
4512 WebRect initialEndRect
;
4516 frame
->executeScript(WebScriptSource("selectCaret();"));
4517 webViewHelper
.webView()->selectionBounds(initialStartRect
, initialEndRect
);
4518 WebPoint
moveTo(topLeft(initialStartRect
));
4521 frame
->moveCaretSelection(moveTo
);
4522 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4523 EXPECT_EQ(startRect
, initialStartRect
);
4524 EXPECT_EQ(endRect
, initialEndRect
);
4527 frame
->moveCaretSelection(moveTo
);
4528 webViewHelper
.webView()->selectionBounds(startRect
, endRect
);
4529 EXPECT_EQ(startRect
, initialStartRect
);
4530 EXPECT_EQ(endRect
, initialEndRect
);
4534 class CompositedSelectionBoundsTestLayerTreeView
: public WebLayerTreeView
{
4536 CompositedSelectionBoundsTestLayerTreeView() : m_selectionCleared(false) { }
4537 ~CompositedSelectionBoundsTestLayerTreeView() override
{ }
4539 void registerSelection(const WebSelection
& selection
) override
4541 m_selection
= adoptPtr(new WebSelection(selection
));
4544 void clearSelection() override
4546 m_selectionCleared
= true;
4547 m_selection
.clear();
4550 bool getAndResetSelectionCleared()
4552 bool selectionCleared
= m_selectionCleared
;
4553 m_selectionCleared
= false;
4554 return selectionCleared
;
4557 const WebSelection
* selection() const { return m_selection
.get(); }
4558 const WebSelectionBound
* start() const { return m_selection
? &m_selection
->start() : nullptr; }
4559 const WebSelectionBound
* end() const { return m_selection
? &m_selection
->end() : nullptr; }
4562 bool m_selectionCleared
;
4563 OwnPtr
<WebSelection
> m_selection
;
4566 class CompositedSelectionBoundsTestWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
4568 ~CompositedSelectionBoundsTestWebViewClient() override
{}
4569 WebLayerTreeView
* layerTreeView() override
{ return &m_testLayerTreeView
; }
4571 CompositedSelectionBoundsTestLayerTreeView
& selectionLayerTreeView() { return m_testLayerTreeView
; }
4574 CompositedSelectionBoundsTestLayerTreeView m_testLayerTreeView
;
4577 class CompositedSelectionBoundsTest
: public WebFrameTest
{
4579 CompositedSelectionBoundsTest()
4580 : m_fakeSelectionLayerTreeView(m_fakeSelectionWebViewClient
.selectionLayerTreeView())
4582 RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);
4583 registerMockedHttpURLLoad("Ahem.ttf");
4585 m_webViewHelper
.initialize(true, 0, &m_fakeSelectionWebViewClient
);
4586 m_webViewHelper
.webView()->settings()->setDefaultFontSize(12);
4587 m_webViewHelper
.webView()->setDefaultPageScaleLimits(1, 1);
4588 m_webViewHelper
.webView()->resize(WebSize(640, 480));
4591 void runTest(const char* testFile
)
4593 registerMockedHttpURLLoad(testFile
);
4594 FrameTestHelpers::loadFrame(m_webViewHelper
.webView()->mainFrame(), m_baseURL
+ testFile
);
4595 m_webViewHelper
.webView()->layout();
4597 const WebSelection
* selection
= m_fakeSelectionLayerTreeView
.selection();
4598 const WebSelectionBound
* selectStart
= m_fakeSelectionLayerTreeView
.start();
4599 const WebSelectionBound
* selectEnd
= m_fakeSelectionLayerTreeView
.end();
4601 v8::HandleScope
handleScope(v8::Isolate::GetCurrent());
4602 v8::Local
<v8::Value
> result
= m_webViewHelper
.webView()->mainFrame()->toWebLocalFrame()->executeScriptAndReturnValue(WebScriptSource("expectedResult"));
4603 if (result
.IsEmpty() || (*result
)->IsUndefined()) {
4604 EXPECT_FALSE(selection
);
4605 EXPECT_FALSE(selectStart
);
4606 EXPECT_FALSE(selectEnd
);
4610 ASSERT_TRUE(selection
);
4611 ASSERT_TRUE(selectStart
);
4612 ASSERT_TRUE(selectEnd
);
4614 EXPECT_FALSE(selection
->isNone());
4616 ASSERT_TRUE((*result
)->IsArray());
4617 v8::Array
& expectedResult
= *v8::Array::Cast(*result
);
4618 ASSERT_GE(expectedResult
.Length(), 10u);
4620 blink::Node
* layerOwnerNodeForStart
= V8Node::toImplWithTypeCheck(v8::Isolate::GetCurrent(), expectedResult
.Get(0));
4621 ASSERT_TRUE(layerOwnerNodeForStart
);
4622 EXPECT_EQ(layerOwnerNodeForStart
->layoutObject()->enclosingLayer()->enclosingLayerForPaintInvalidation()->graphicsLayerBacking()->platformLayer()->id(), selectStart
->layerId
);
4623 v8::Local
<v8::Context
> context
= v8::Isolate::GetCurrent()->GetCurrentContext();
4624 EXPECT_EQ(expectedResult
.Get(context
, 1).ToLocalChecked().As
<v8::Int32
>()->Value(), selectStart
->edgeTopInLayer
.x
);
4625 EXPECT_EQ(expectedResult
.Get(context
, 2).ToLocalChecked().As
<v8::Int32
>()->Value(), selectStart
->edgeTopInLayer
.y
);
4626 EXPECT_EQ(expectedResult
.Get(context
, 3).ToLocalChecked().As
<v8::Int32
>()->Value(), selectStart
->edgeBottomInLayer
.x
);
4628 blink::Node
* layerOwnerNodeForEnd
= V8Node::toImplWithTypeCheck(v8::Isolate::GetCurrent(), expectedResult
.Get(context
, 5).ToLocalChecked());
4630 ASSERT_TRUE(layerOwnerNodeForEnd
);
4631 EXPECT_EQ(layerOwnerNodeForEnd
->layoutObject()->enclosingLayer()->enclosingLayerForPaintInvalidation()->graphicsLayerBacking()->platformLayer()->id(), selectEnd
->layerId
);
4632 EXPECT_EQ(expectedResult
.Get(context
, 6).ToLocalChecked().As
<v8::Int32
>()->Value(), selectEnd
->edgeTopInLayer
.x
);
4633 EXPECT_EQ(expectedResult
.Get(context
, 7).ToLocalChecked().As
<v8::Int32
>()->Value(), selectEnd
->edgeTopInLayer
.y
);
4634 EXPECT_EQ(expectedResult
.Get(context
, 8).ToLocalChecked().As
<v8::Int32
>()->Value(), selectEnd
->edgeBottomInLayer
.x
);
4636 // Platform differences can introduce small stylistic deviations in
4637 // y-axis positioning, the details of which aren't relevant to
4638 // selection behavior. However, such deviations from the expected value
4639 // should be consistent for the corresponding y coordinates.
4640 int yBottomEpsilon
= 0;
4641 if (expectedResult
.Length() == 13)
4642 yBottomEpsilon
= expectedResult
.Get(context
, 12).ToLocalChecked().As
<v8::Int32
>()->Value();
4643 int yBottomDeviation
= expectedResult
.Get(context
, 4).ToLocalChecked().As
<v8::Int32
>()->Value() - selectStart
->edgeBottomInLayer
.y
;
4644 EXPECT_GE(yBottomEpsilon
, std::abs(yBottomDeviation
));
4645 EXPECT_EQ(yBottomDeviation
, expectedResult
.Get(context
, 9).ToLocalChecked().As
<v8::Int32
>()->Value() - selectEnd
->edgeBottomInLayer
.y
);
4647 if (expectedResult
.Length() >= 12) {
4648 EXPECT_EQ(expectedResult
.Get(context
, 10).ToLocalChecked().As
<v8::Boolean
>()->Value(), m_fakeSelectionLayerTreeView
.selection()->isEditable());
4649 EXPECT_EQ(expectedResult
.Get(context
, 11).ToLocalChecked().As
<v8::Boolean
>()->Value(), m_fakeSelectionLayerTreeView
.selection()->isEmptyTextFormControl());
4653 void runTestWithMultipleFiles(const char* testFile
, ...)
4656 va_start(auxFiles
, testFile
);
4657 while (const char* auxFile
= va_arg(auxFiles
, const char*))
4658 registerMockedHttpURLLoad(auxFile
);
4664 CompositedSelectionBoundsTestWebViewClient m_fakeSelectionWebViewClient
;
4665 CompositedSelectionBoundsTestLayerTreeView
& m_fakeSelectionLayerTreeView
;
4666 FrameTestHelpers::WebViewHelper m_webViewHelper
;
4669 TEST_F(CompositedSelectionBoundsTest
, None
) { runTest("composited_selection_bounds_none.html"); }
4670 TEST_F(CompositedSelectionBoundsTest
, NoneReadonlyCaret
) { runTest("composited_selection_bounds_none_readonly_caret.html"); }
4671 TEST_F(CompositedSelectionBoundsTest
, Basic
) { runTest("composited_selection_bounds_basic.html"); }
4672 TEST_F(CompositedSelectionBoundsTest
, Transformed
) { runTest("composited_selection_bounds_transformed.html"); }
4673 TEST_F(CompositedSelectionBoundsTest
, SplitLayer
) { runTest("composited_selection_bounds_split_layer.html"); }
4674 TEST_F(CompositedSelectionBoundsTest
, EmptyLayer
) { runTest("composited_selection_bounds_empty_layer.html"); }
4675 TEST_F(CompositedSelectionBoundsTest
, Iframe
) { runTestWithMultipleFiles("composited_selection_bounds_iframe.html", "composited_selection_bounds_basic.html", nullptr); }
4676 TEST_F(CompositedSelectionBoundsTest
, DetachedFrame
) { runTest("composited_selection_bounds_detached_frame.html"); }
4677 TEST_F(CompositedSelectionBoundsTest
, Editable
) { runTest("composited_selection_bounds_editable.html"); }
4678 TEST_F(CompositedSelectionBoundsTest
, EditableDiv
) { runTest("composited_selection_bounds_editable_div.html"); }
4679 TEST_F(CompositedSelectionBoundsTest
, EmptyEditableInput
) { runTest("composited_selection_bounds_empty_editable_input.html"); }
4680 TEST_F(CompositedSelectionBoundsTest
, EmptyEditableArea
) { runTest("composited_selection_bounds_empty_editable_area.html"); }
4682 TEST_P(ParameterizedWebFrameTest
, CompositedSelectionBoundsCleared
)
4684 RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);
4686 registerMockedHttpURLLoad("select_range_basic.html");
4687 registerMockedHttpURLLoad("select_range_scroll.html");
4689 int viewWidth
= 500;
4690 int viewHeight
= 500;
4692 CompositedSelectionBoundsTestWebViewClient fakeSelectionWebViewClient
;
4693 CompositedSelectionBoundsTestLayerTreeView
& fakeSelectionLayerTreeView
= fakeSelectionWebViewClient
.selectionLayerTreeView();
4695 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4696 webViewHelper
.initialize(true, 0, &fakeSelectionWebViewClient
);
4697 webViewHelper
.webView()->settings()->setDefaultFontSize(12);
4698 webViewHelper
.webView()->setDefaultPageScaleLimits(1, 1);
4699 webViewHelper
.webView()->resize(WebSize(viewWidth
, viewHeight
));
4700 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "select_range_basic.html");
4702 // The frame starts with a non-empty selection.
4703 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
4704 ASSERT_TRUE(frame
->hasSelection());
4705 EXPECT_FALSE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4707 // The selection cleared notification should be triggered upon layout.
4708 frame
->executeCommand(WebString::fromUTF8("Unselect"));
4709 ASSERT_FALSE(frame
->hasSelection());
4710 EXPECT_FALSE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4711 webViewHelper
.webView()->layout();
4712 EXPECT_TRUE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4714 frame
->executeCommand(WebString::fromUTF8("SelectAll"));
4715 webViewHelper
.webView()->layout();
4716 ASSERT_TRUE(frame
->hasSelection());
4717 EXPECT_FALSE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4719 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "select_range_scroll.html");
4720 ASSERT_TRUE(frame
->hasSelection());
4721 EXPECT_FALSE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4723 // Transitions between non-empty selections should not trigger a clearing.
4724 WebRect startWebRect
;
4726 webViewHelper
.webViewImpl()->selectionBounds(startWebRect
, endWebRect
);
4727 WebPoint
movedEnd(bottomRightMinusOne(endWebRect
));
4729 frame
->selectRange(topLeft(startWebRect
), movedEnd
);
4730 webViewHelper
.webView()->layout();
4731 ASSERT_TRUE(frame
->hasSelection());
4732 EXPECT_FALSE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4734 frame
= webViewHelper
.webView()->mainFrame();
4735 frame
->executeCommand(WebString::fromUTF8("Unselect"));
4736 webViewHelper
.webView()->layout();
4737 ASSERT_FALSE(frame
->hasSelection());
4738 EXPECT_TRUE(fakeSelectionLayerTreeView
.getAndResetSelectionCleared());
4741 class DisambiguationPopupTestWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
4743 bool didTapMultipleTargets(const WebSize
&, const WebRect
&, const WebVector
<WebRect
>& targetRects
) override
4745 EXPECT_GE(targetRects
.size(), 2u);
4750 bool triggered() const { return m_triggered
; }
4751 void resetTriggered() { m_triggered
= false; }
4755 static WebGestureEvent
fatTap(int x
, int y
)
4757 WebGestureEvent event
;
4758 event
.type
= WebInputEvent::GestureTap
;
4761 event
.data
.tap
.width
= 50;
4762 event
.data
.tap
.height
= 50;
4766 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopup
)
4768 const std::string htmlFile
= "disambiguation_popup.html";
4769 registerMockedHttpURLLoad(htmlFile
);
4771 DisambiguationPopupTestWebViewClient client
;
4773 // Make sure we initialize to minimum scale, even if the window size
4774 // only becomes available after the load begins.
4775 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4776 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
);
4777 webViewHelper
.webView()->resize(WebSize(1000, 1000));
4778 webViewHelper
.webView()->layout();
4780 client
.resetTriggered();
4781 webViewHelper
.webView()->handleInputEvent(fatTap(0, 0));
4782 EXPECT_FALSE(client
.triggered());
4784 client
.resetTriggered();
4785 webViewHelper
.webView()->handleInputEvent(fatTap(200, 115));
4786 EXPECT_FALSE(client
.triggered());
4788 for (int i
= 0; i
<= 46; i
++) {
4789 client
.resetTriggered();
4790 webViewHelper
.webView()->handleInputEvent(fatTap(120, 230 + i
* 5));
4793 if (j
>= 7 && j
<= 9)
4794 EXPECT_TRUE(client
.triggered());
4796 EXPECT_FALSE(client
.triggered());
4799 for (int i
= 0; i
<= 46; i
++) {
4800 client
.resetTriggered();
4801 webViewHelper
.webView()->handleInputEvent(fatTap(10 + i
* 5, 590));
4804 if (j
>= 7 && j
<= 9)
4805 EXPECT_TRUE(client
.triggered());
4807 EXPECT_FALSE(client
.triggered());
4810 // The same taps shouldn't trigger didTapMultipleTargets() after disabling the notification for
4811 // multi-target-tap.
4812 webViewHelper
.webView()->settings()->setMultiTargetTapNotificationEnabled(false);
4814 for (int i
= 0; i
<= 46; i
++) {
4815 client
.resetTriggered();
4816 webViewHelper
.webView()->handleInputEvent(fatTap(10 + i
* 5, 590));
4817 EXPECT_FALSE(client
.triggered());
4821 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopupNoContainer
)
4823 registerMockedHttpURLLoad("disambiguation_popup_no_container.html");
4825 DisambiguationPopupTestWebViewClient client
;
4827 // Make sure we initialize to minimum scale, even if the window size
4828 // only becomes available after the load begins.
4829 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4830 webViewHelper
.initializeAndLoad(m_baseURL
+ "disambiguation_popup_no_container.html", true, 0, &client
);
4831 webViewHelper
.webView()->resize(WebSize(1000, 1000));
4832 webViewHelper
.webView()->layout();
4834 client
.resetTriggered();
4835 webViewHelper
.webView()->handleInputEvent(fatTap(50, 50));
4836 EXPECT_FALSE(client
.triggered());
4839 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopupMobileSite
)
4841 UseMockScrollbarSettings mockScrollbarSettings
;
4842 const std::string htmlFile
= "disambiguation_popup_mobile_site.html";
4843 registerMockedHttpURLLoad(htmlFile
);
4845 DisambiguationPopupTestWebViewClient client
;
4847 // Make sure we initialize to minimum scale, even if the window size
4848 // only becomes available after the load begins.
4849 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4850 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
, enableViewportSettings
);
4851 webViewHelper
.webView()->resize(WebSize(1000, 1000));
4852 webViewHelper
.webView()->layout();
4854 client
.resetTriggered();
4855 webViewHelper
.webView()->handleInputEvent(fatTap(0, 0));
4856 EXPECT_FALSE(client
.triggered());
4858 client
.resetTriggered();
4859 webViewHelper
.webView()->handleInputEvent(fatTap(200, 115));
4860 EXPECT_FALSE(client
.triggered());
4862 for (int i
= 0; i
<= 46; i
++) {
4863 client
.resetTriggered();
4864 webViewHelper
.webView()->handleInputEvent(fatTap(120, 230 + i
* 5));
4865 EXPECT_FALSE(client
.triggered());
4868 for (int i
= 0; i
<= 46; i
++) {
4869 client
.resetTriggered();
4870 webViewHelper
.webView()->handleInputEvent(fatTap(10 + i
* 5, 590));
4871 EXPECT_FALSE(client
.triggered());
4875 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopupViewportSite
)
4877 UseMockScrollbarSettings mockScrollbarSettings
;
4878 const std::string htmlFile
= "disambiguation_popup_viewport_site.html";
4879 registerMockedHttpURLLoad(htmlFile
);
4881 DisambiguationPopupTestWebViewClient client
;
4883 // Make sure we initialize to minimum scale, even if the window size
4884 // only becomes available after the load begins.
4885 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4886 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
, enableViewportSettings
);
4887 webViewHelper
.webView()->resize(WebSize(1000, 1000));
4888 webViewHelper
.webView()->layout();
4890 client
.resetTriggered();
4891 webViewHelper
.webView()->handleInputEvent(fatTap(0, 0));
4892 EXPECT_FALSE(client
.triggered());
4894 client
.resetTriggered();
4895 webViewHelper
.webView()->handleInputEvent(fatTap(200, 115));
4896 EXPECT_FALSE(client
.triggered());
4898 for (int i
= 0; i
<= 46; i
++) {
4899 client
.resetTriggered();
4900 webViewHelper
.webView()->handleInputEvent(fatTap(120, 230 + i
* 5));
4901 EXPECT_FALSE(client
.triggered());
4904 for (int i
= 0; i
<= 46; i
++) {
4905 client
.resetTriggered();
4906 webViewHelper
.webView()->handleInputEvent(fatTap(10 + i
* 5, 590));
4907 EXPECT_FALSE(client
.triggered());
4911 TEST_F(WebFrameTest
, DisambiguationPopupVisualViewport
)
4913 UseMockScrollbarSettings mockScrollbarSettings
;
4914 const std::string htmlFile
= "disambiguation_popup_200_by_800.html";
4915 registerMockedHttpURLLoad(htmlFile
);
4917 DisambiguationPopupTestWebViewClient client
;
4919 FrameTestHelpers::WebViewHelper webViewHelper
;
4920 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
, configureAndroid
);
4922 WebViewImpl
* webViewImpl
= webViewHelper
.webViewImpl();
4923 ASSERT_TRUE(webViewImpl
);
4924 LocalFrame
* frame
= webViewImpl
->mainFrameImpl()->frame();
4927 webViewHelper
.webView()->resize(WebSize(100, 200));
4929 // Scroll main frame to the bottom of the document
4930 webViewImpl
->mainFrame()->setScrollOffset(WebSize(0, 400));
4931 EXPECT_POINT_EQ(IntPoint(0, 400), frame
->view()->scrollPosition());
4933 webViewImpl
->setPageScaleFactor(2.0);
4935 // Scroll visual viewport to the top of the main frame.
4936 VisualViewport
& visualViewport
= frame
->page()->frameHost().visualViewport();
4937 visualViewport
.setLocation(FloatPoint(0, 0));
4938 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 0), visualViewport
.location());
4940 // Tap at the top: there is nothing there.
4941 client
.resetTriggered();
4942 webViewHelper
.webView()->handleInputEvent(fatTap(10, 60));
4943 EXPECT_FALSE(client
.triggered());
4945 // Scroll visual viewport to the bottom of the main frame.
4946 visualViewport
.setLocation(FloatPoint(0, 200));
4947 EXPECT_FLOAT_POINT_EQ(FloatPoint(0, 200), visualViewport
.location());
4949 // Now the tap with the same coordinates should hit two elements.
4950 client
.resetTriggered();
4951 webViewHelper
.webView()->handleInputEvent(fatTap(10, 60));
4952 EXPECT_TRUE(client
.triggered());
4954 // The same tap shouldn't trigger didTapMultipleTargets() after disabling the notification for
4955 // multi-target-tap.
4956 webViewHelper
.webView()->settings()->setMultiTargetTapNotificationEnabled(false);
4957 client
.resetTriggered();
4958 webViewHelper
.webView()->handleInputEvent(fatTap(10, 60));
4959 EXPECT_FALSE(client
.triggered());
4962 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopupBlacklist
)
4964 const unsigned viewportWidth
= 500;
4965 const unsigned viewportHeight
= 1000;
4966 const unsigned divHeight
= 100;
4967 const std::string htmlFile
= "disambiguation_popup_blacklist.html";
4968 registerMockedHttpURLLoad(htmlFile
);
4970 DisambiguationPopupTestWebViewClient client
;
4972 // Make sure we initialize to minimum scale, even if the window size
4973 // only becomes available after the load begins.
4974 FrameTestHelpers::WebViewHelper
webViewHelper(this);
4975 webViewHelper
.initializeAndLoad(m_baseURL
+ htmlFile
, true, 0, &client
);
4976 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
4977 webViewHelper
.webView()->layout();
4979 // Click somewhere where the popup shouldn't appear.
4980 client
.resetTriggered();
4981 webViewHelper
.webView()->handleInputEvent(fatTap(viewportWidth
/ 2, 0));
4982 EXPECT_FALSE(client
.triggered());
4984 // Click directly in between two container divs with click handlers, with children that don't handle clicks.
4985 client
.resetTriggered();
4986 webViewHelper
.webView()->handleInputEvent(fatTap(viewportWidth
/ 2, divHeight
));
4987 EXPECT_TRUE(client
.triggered());
4989 // The third div container should be blacklisted if you click on the link it contains.
4990 client
.resetTriggered();
4991 webViewHelper
.webView()->handleInputEvent(fatTap(viewportWidth
/ 2, divHeight
* 3.25));
4992 EXPECT_FALSE(client
.triggered());
4995 TEST_P(ParameterizedWebFrameTest
, DisambiguationPopupPageScale
)
4997 registerMockedHttpURLLoad("disambiguation_popup_page_scale.html");
4999 DisambiguationPopupTestWebViewClient client
;
5001 // Make sure we initialize to minimum scale, even if the window size
5002 // only becomes available after the load begins.
5003 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5004 webViewHelper
.initializeAndLoad(m_baseURL
+ "disambiguation_popup_page_scale.html", true, 0, &client
);
5005 webViewHelper
.webView()->resize(WebSize(1000, 1000));
5006 webViewHelper
.webView()->layout();
5008 client
.resetTriggered();
5009 webViewHelper
.webView()->handleInputEvent(fatTap(80, 80));
5010 EXPECT_TRUE(client
.triggered());
5012 client
.resetTriggered();
5013 webViewHelper
.webView()->handleInputEvent(fatTap(230, 190));
5014 EXPECT_TRUE(client
.triggered());
5016 webViewHelper
.webView()->setPageScaleFactor(3.0f
);
5017 webViewHelper
.webView()->layout();
5019 client
.resetTriggered();
5020 webViewHelper
.webView()->handleInputEvent(fatTap(240, 240));
5021 EXPECT_TRUE(client
.triggered());
5023 client
.resetTriggered();
5024 webViewHelper
.webView()->handleInputEvent(fatTap(690, 570));
5025 EXPECT_FALSE(client
.triggered());
5028 class TestSubstituteDataWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5030 TestSubstituteDataWebFrameClient()
5031 : m_commitCalled(false)
5035 virtual void didFailProvisionalLoad(WebLocalFrame
* frame
, const WebURLError
& error
, WebHistoryCommitType
)
5037 frame
->loadHTMLString("This should appear", toKURL("data:text/html,chromewebdata"), error
.unreachableURL
, true);
5040 virtual void didCommitProvisionalLoad(WebLocalFrame
* frame
, const WebHistoryItem
&, WebHistoryCommitType
)
5042 if (frame
->dataSource()->response().url() != WebURL(URLTestHelpers::toKURL("about:blank")))
5043 m_commitCalled
= true;
5046 bool commitCalled() const { return m_commitCalled
; }
5049 bool m_commitCalled
;
5052 TEST_P(ParameterizedWebFrameTest
, ReplaceNavigationAfterHistoryNavigation
)
5054 TestSubstituteDataWebFrameClient webFrameClient
;
5056 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5057 webViewHelper
.initializeAndLoad("about:blank", true, &webFrameClient
);
5058 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
5060 // Load a url as a history navigation that will return an error. TestSubstituteDataWebFrameClient
5061 // will start a SubstituteData load in response to the load failure, which should get fully committed.
5062 // Due to https://bugs.webkit.org/show_bug.cgi?id=91685, FrameLoader::didReceiveData() wasn't getting
5063 // called in this case, which resulted in the SubstituteData document not getting displayed.
5065 error
.reason
= 1337;
5066 error
.domain
= "WebFrameTest";
5067 std::string errorURL
= "http://0.0.0.0";
5068 WebURLResponse response
;
5069 response
.initialize();
5070 response
.setURL(URLTestHelpers::toKURL(errorURL
));
5071 response
.setMIMEType("text/html");
5072 response
.setHTTPStatusCode(500);
5073 WebHistoryItem errorHistoryItem
;
5074 errorHistoryItem
.initialize();
5075 errorHistoryItem
.setURLString(WebString::fromUTF8(errorURL
.c_str(), errorURL
.length()));
5076 Platform::current()->unitTestSupport()->registerMockedErrorURL(URLTestHelpers::toKURL(errorURL
), response
, error
);
5077 FrameTestHelpers::loadHistoryItem(frame
, errorHistoryItem
, WebHistoryDifferentDocumentLoad
, WebURLRequest::UseProtocolCachePolicy
);
5079 WebString text
= frame
->contentAsText(std::numeric_limits
<size_t>::max());
5080 EXPECT_EQ("This should appear", text
.utf8());
5081 EXPECT_TRUE(webFrameClient
.commitCalled());
5084 class TestWillInsertBodyWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5086 TestWillInsertBodyWebFrameClient() : m_numBodies(0), m_didLoad(false)
5090 void didCommitProvisionalLoad(WebLocalFrame
*, const WebHistoryItem
&, WebHistoryCommitType
) override
5096 void didCreateDocumentElement(WebLocalFrame
*) override
5098 EXPECT_EQ(0, m_numBodies
);
5101 void willInsertBody(WebLocalFrame
*) override
5110 TEST_P(ParameterizedWebFrameTest
, HTMLDocument
)
5112 registerMockedHttpURLLoad("clipped-body.html");
5114 TestWillInsertBodyWebFrameClient webFrameClient
;
5115 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5116 webViewHelper
.initializeAndLoad(m_baseURL
+ "clipped-body.html", false, &webFrameClient
);
5118 EXPECT_TRUE(webFrameClient
.m_didLoad
);
5119 EXPECT_EQ(1, webFrameClient
.m_numBodies
);
5122 TEST_P(ParameterizedWebFrameTest
, EmptyDocument
)
5124 registerMockedHttpURLLoad("pageserializer/svg/green_rectangle.svg");
5126 TestWillInsertBodyWebFrameClient webFrameClient
;
5127 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5128 webViewHelper
.initialize(false, &webFrameClient
);
5130 EXPECT_FALSE(webFrameClient
.m_didLoad
);
5131 EXPECT_EQ(1, webFrameClient
.m_numBodies
); // The empty document that a new frame starts with triggers this.
5134 TEST_P(ParameterizedWebFrameTest
, MoveCaretSelectionTowardsWindowPointWithNoSelection
)
5136 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5137 webViewHelper
.initializeAndLoad("about:blank", true);
5138 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
5140 // This test passes if this doesn't crash.
5141 frame
->moveCaretSelection(WebPoint(0, 0));
5144 class SpellCheckClient
: public WebSpellCheckClient
{
5146 explicit SpellCheckClient(uint32_t hash
= 0) : m_numberOfTimesChecked(0), m_hash(hash
) { }
5147 virtual ~SpellCheckClient() { }
5148 void requestCheckingOfText(const WebString
&, const WebVector
<uint32_t>&, const WebVector
<unsigned>&, WebTextCheckingCompletion
* completion
) override
5150 ++m_numberOfTimesChecked
;
5151 Vector
<WebTextCheckingResult
> results
;
5152 const int misspellingStartOffset
= 1;
5153 const int misspellingLength
= 8;
5154 results
.append(WebTextCheckingResult(WebTextDecorationTypeSpelling
, misspellingStartOffset
, misspellingLength
, WebString(), m_hash
));
5155 completion
->didFinishCheckingText(results
);
5157 int numberOfTimesChecked() const { return m_numberOfTimesChecked
; }
5159 int m_numberOfTimesChecked
;
5163 TEST_P(ParameterizedWebFrameTest
, ReplaceMisspelledRange
)
5165 registerMockedHttpURLLoad("spell.html");
5166 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5167 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5168 SpellCheckClient spellcheck
;
5169 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5171 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5172 Document
* document
= frame
->frame()->document();
5173 Element
* element
= document
->getElementById("data");
5175 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5176 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5177 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5180 NonThrowableExceptionState exceptionState
;
5181 document
->execCommand("InsertText", false, "_wellcome_.", exceptionState
);
5182 EXPECT_FALSE(exceptionState
.hadException());
5184 const int allTextBeginOffset
= 0;
5185 const int allTextLength
= 11;
5186 frame
->selectRange(WebRange::fromDocumentRange(frame
, allTextBeginOffset
, allTextLength
));
5187 EphemeralRange selectionRange
= frame
->frame()->selection().selection().toNormalizedEphemeralRange();
5189 EXPECT_EQ(1, spellcheck
.numberOfTimesChecked());
5190 EXPECT_EQ(1U, document
->markers().markersInRange(selectionRange
, DocumentMarker::Spelling
).size());
5192 frame
->replaceMisspelledRange("welcome");
5193 EXPECT_EQ("_welcome_.", frame
->contentAsText(std::numeric_limits
<size_t>::max()).utf8());
5196 TEST_P(ParameterizedWebFrameTest
, RemoveSpellingMarkers
)
5198 registerMockedHttpURLLoad("spell.html");
5199 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5200 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5201 SpellCheckClient spellcheck
;
5202 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5204 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5205 Document
* document
= frame
->frame()->document();
5206 Element
* element
= document
->getElementById("data");
5208 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5209 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5210 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5213 NonThrowableExceptionState exceptionState
;
5214 document
->execCommand("InsertText", false, "_wellcome_.", exceptionState
);
5215 EXPECT_FALSE(exceptionState
.hadException());
5217 frame
->removeSpellingMarkers();
5219 const int allTextBeginOffset
= 0;
5220 const int allTextLength
= 11;
5221 frame
->selectRange(WebRange::fromDocumentRange(frame
, allTextBeginOffset
, allTextLength
));
5222 EphemeralRange selectionRange
= frame
->frame()->selection().selection().toNormalizedEphemeralRange();
5224 EXPECT_EQ(0U, document
->markers().markersInRange(selectionRange
, DocumentMarker::Spelling
).size());
5227 TEST_P(ParameterizedWebFrameTest
, RemoveSpellingMarkersUnderWords
)
5229 registerMockedHttpURLLoad("spell.html");
5230 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5231 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5232 SpellCheckClient spellcheck
;
5233 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5235 LocalFrame
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame())->frame();
5236 Document
* document
= frame
->document();
5237 Element
* element
= document
->getElementById("data");
5239 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5240 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5241 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5244 NonThrowableExceptionState exceptionState
;
5245 document
->execCommand("InsertText", false, " wellcome ", exceptionState
);
5246 EXPECT_FALSE(exceptionState
.hadException());
5248 WebVector
<uint32_t> documentMarkers1
;
5249 webViewHelper
.webView()->spellingMarkers(&documentMarkers1
);
5250 EXPECT_EQ(1U, documentMarkers1
.size());
5252 Vector
<String
> words
;
5253 words
.append("wellcome");
5254 frame
->removeSpellingMarkersUnderWords(words
);
5256 WebVector
<uint32_t> documentMarkers2
;
5257 webViewHelper
.webView()->spellingMarkers(&documentMarkers2
);
5258 EXPECT_EQ(0U, documentMarkers2
.size());
5261 TEST_P(ParameterizedWebFrameTest
, MarkerHashIdentifiers
)
5263 registerMockedHttpURLLoad("spell.html");
5264 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5265 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5267 static const uint32_t kHash
= 42;
5268 SpellCheckClient
spellcheck(kHash
);
5269 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5271 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5272 Document
* document
= frame
->frame()->document();
5273 Element
* element
= document
->getElementById("data");
5275 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5276 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5277 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5280 NonThrowableExceptionState exceptionState
;
5281 document
->execCommand("InsertText", false, "wellcome.", exceptionState
);
5282 EXPECT_FALSE(exceptionState
.hadException());
5284 WebVector
<uint32_t> documentMarkers
;
5285 webViewHelper
.webView()->spellingMarkers(&documentMarkers
);
5286 EXPECT_EQ(1U, documentMarkers
.size());
5287 EXPECT_EQ(kHash
, documentMarkers
[0]);
5290 class StubbornSpellCheckClient
: public WebSpellCheckClient
{
5292 StubbornSpellCheckClient() : m_completion(0) { }
5293 virtual ~StubbornSpellCheckClient() { }
5295 virtual void requestCheckingOfText(
5297 const WebVector
<uint32_t>&,
5298 const WebVector
<unsigned>&,
5299 WebTextCheckingCompletion
* completion
) override
5301 m_completion
= completion
;
5304 void kickNoResults()
5306 kick(-1, -1, WebTextDecorationTypeSpelling
);
5311 kick(1, 8, WebTextDecorationTypeSpelling
);
5316 kick(1, 8, WebTextDecorationTypeGrammar
);
5319 void kickInvisibleSpellcheck()
5321 kick(1, 8, WebTextDecorationTypeInvisibleSpellcheck
);
5325 void kick(int misspellingStartOffset
, int misspellingLength
, WebTextDecorationType type
)
5329 Vector
<WebTextCheckingResult
> results
;
5330 if (misspellingStartOffset
>= 0 && misspellingLength
> 0)
5331 results
.append(WebTextCheckingResult(type
, misspellingStartOffset
, misspellingLength
));
5332 m_completion
->didFinishCheckingText(results
);
5336 WebTextCheckingCompletion
* m_completion
;
5339 TEST_P(ParameterizedWebFrameTest
, SlowSpellcheckMarkerPosition
)
5341 registerMockedHttpURLLoad("spell.html");
5342 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5343 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5345 StubbornSpellCheckClient spellcheck
;
5346 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5348 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5349 WebInputElement webInputElement
= frame
->document().getElementById("data").to
<WebInputElement
>();
5350 Document
* document
= frame
->frame()->document();
5351 Element
* element
= document
->getElementById("data");
5353 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5354 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5355 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5358 NonThrowableExceptionState exceptionState
;
5359 document
->execCommand("InsertText", false, "wellcome ", exceptionState
);
5360 EXPECT_FALSE(exceptionState
.hadException());
5361 webInputElement
.setSelectionRange(0, 0);
5362 document
->execCommand("InsertText", false, "he", exceptionState
);
5363 EXPECT_FALSE(exceptionState
.hadException());
5367 WebVector
<uint32_t> documentMarkers
;
5368 webViewHelper
.webView()->spellingMarkers(&documentMarkers
);
5369 EXPECT_EQ(0U, documentMarkers
.size());
5372 // This test verifies that cancelling spelling request does not cause a
5373 // write-after-free when there's no spellcheck client set.
5374 TEST_P(ParameterizedWebFrameTest
, CancelSpellingRequestCrash
)
5376 registerMockedHttpURLLoad("spell.html");
5377 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5378 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5379 webViewHelper
.webView()->setSpellCheckClient(0);
5381 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5382 Document
* document
= frame
->frame()->document();
5383 Element
* element
= document
->getElementById("data");
5385 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5386 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5387 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5390 frame
->frame()->editor().replaceSelectionWithText("A", false, false);
5391 frame
->frame()->spellChecker().cancelCheck();
5394 TEST_P(ParameterizedWebFrameTest
, SpellcheckResultErasesMarkers
)
5396 registerMockedHttpURLLoad("spell.html");
5397 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5398 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5400 StubbornSpellCheckClient spellcheck
;
5401 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5403 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5404 WebInputElement webInputElement
= frame
->document().getElementById("data").to
<WebInputElement
>();
5405 Document
* document
= frame
->frame()->document();
5406 Element
* element
= document
->getElementById("data");
5408 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5409 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5410 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5413 NonThrowableExceptionState exceptionState
;
5414 document
->execCommand("InsertText", false, "welcome ", exceptionState
);
5415 EXPECT_FALSE(exceptionState
.hadException());
5416 auto range
= EphemeralRange::rangeOfContents(*element
);
5417 document
->markers().addMarker(range
.startPosition(), range
.endPosition(), DocumentMarker::Spelling
);
5418 document
->markers().addMarker(range
.startPosition(), range
.endPosition(), DocumentMarker::Grammar
);
5419 document
->markers().addMarker(range
.startPosition(), range
.endPosition(), DocumentMarker::InvisibleSpellcheck
);
5420 EXPECT_EQ(3U, document
->markers().markers().size());
5422 spellcheck
.kickNoResults();
5423 EXPECT_EQ(0U, document
->markers().markers().size());
5426 TEST_P(ParameterizedWebFrameTest
, SpellcheckResultsSavedInDocument
)
5428 registerMockedHttpURLLoad("spell.html");
5429 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5430 webViewHelper
.initializeAndLoad(m_baseURL
+ "spell.html");
5432 StubbornSpellCheckClient spellcheck
;
5433 webViewHelper
.webView()->setSpellCheckClient(&spellcheck
);
5435 WebLocalFrameImpl
* frame
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame());
5436 WebInputElement webInputElement
= frame
->document().getElementById("data").to
<WebInputElement
>();
5437 Document
* document
= frame
->frame()->document();
5438 Element
* element
= document
->getElementById("data");
5440 webViewHelper
.webView()->settings()->setAsynchronousSpellCheckingEnabled(true);
5441 webViewHelper
.webView()->settings()->setUnifiedTextCheckerEnabled(true);
5442 webViewHelper
.webView()->settings()->setEditingBehavior(WebSettings::EditingBehaviorWin
);
5445 NonThrowableExceptionState exceptionState
;
5446 document
->execCommand("InsertText", false, "wellcome ", exceptionState
);
5447 EXPECT_FALSE(exceptionState
.hadException());
5450 ASSERT_EQ(1U, document
->markers().markers().size());
5451 ASSERT_NE(static_cast<DocumentMarker
*>(0), document
->markers().markers()[0]);
5452 EXPECT_EQ(DocumentMarker::Spelling
, document
->markers().markers()[0]->type());
5454 document
->execCommand("InsertText", false, "wellcome ", exceptionState
);
5455 EXPECT_FALSE(exceptionState
.hadException());
5457 spellcheck
.kickGrammar();
5458 ASSERT_EQ(1U, document
->markers().markers().size());
5459 ASSERT_NE(static_cast<DocumentMarker
*>(0), document
->markers().markers()[0]);
5460 EXPECT_EQ(DocumentMarker::Grammar
, document
->markers().markers()[0]->type());
5462 document
->execCommand("InsertText", false, "wellcome ", exceptionState
);
5463 EXPECT_FALSE(exceptionState
.hadException());
5465 spellcheck
.kickInvisibleSpellcheck();
5466 ASSERT_EQ(1U, document
->markers().markers().size());
5467 ASSERT_NE(static_cast<DocumentMarker
*>(0), document
->markers().markers()[0]);
5468 EXPECT_EQ(DocumentMarker::InvisibleSpellcheck
, document
->markers().markers()[0]->type());
5471 class TestAccessInitialDocumentWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5473 TestAccessInitialDocumentWebFrameClient() : m_didAccessInitialDocument(false)
5477 virtual void didAccessInitialDocument(WebLocalFrame
* frame
)
5479 EXPECT_TRUE(!m_didAccessInitialDocument
);
5480 m_didAccessInitialDocument
= true;
5483 bool m_didAccessInitialDocument
;
5486 TEST_P(ParameterizedWebFrameTest
, DidAccessInitialDocumentBody
)
5488 // FIXME: Why is this local webViewClient needed instead of the default
5489 // WebViewHelper one? With out it there's some mysterious crash in the
5490 // WebViewHelper destructor.
5491 FrameTestHelpers::TestWebViewClient webViewClient
;
5492 TestAccessInitialDocumentWebFrameClient webFrameClient
;
5493 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5494 webViewHelper
.initialize(true, &webFrameClient
, &webViewClient
);
5496 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5498 // Create another window that will try to access it.
5499 FrameTestHelpers::WebViewHelper
newWebViewHelper(this);
5500 WebView
* newView
= newWebViewHelper
.initialize(true);
5501 newView
->mainFrame()->setOpener(webViewHelper
.webView()->mainFrame());
5503 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5505 // Access the initial document by modifying the body.
5506 newView
->mainFrame()->executeScript(
5507 WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
5509 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5511 // Access the initial document again, to ensure we don't notify twice.
5512 newView
->mainFrame()->executeScript(
5513 WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
5515 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5518 TEST_P(ParameterizedWebFrameTest
, DidAccessInitialDocumentNavigator
)
5520 // FIXME: Why is this local webViewClient needed instead of the default
5521 // WebViewHelper one? With out it there's some mysterious crash in the
5522 // WebViewHelper destructor.
5523 FrameTestHelpers::TestWebViewClient webViewClient
;
5524 TestAccessInitialDocumentWebFrameClient webFrameClient
;
5525 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5526 webViewHelper
.initialize(true, &webFrameClient
, &webViewClient
);
5528 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5530 // Create another window that will try to access it.
5531 FrameTestHelpers::WebViewHelper
newWebViewHelper(this);
5532 WebView
* newView
= newWebViewHelper
.initialize(true);
5533 newView
->mainFrame()->setOpener(webViewHelper
.webView()->mainFrame());
5535 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5537 // Access the initial document to get to the navigator object.
5538 newView
->mainFrame()->executeScript(
5539 WebScriptSource("console.log(window.opener.navigator);"));
5541 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5544 TEST_P(ParameterizedWebFrameTest
, DidAccessInitialDocumentViaJavascriptUrl
)
5546 TestAccessInitialDocumentWebFrameClient webFrameClient
;
5547 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5548 webViewHelper
.initialize(true, &webFrameClient
);
5550 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5552 // Access the initial document from a javascript: URL.
5553 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.body.appendChild(document.createTextNode('Modified'))");
5554 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5557 // Fails on the WebKit XP (deps) bot. http://crbug.com/312192
5559 TEST_P(ParameterizedWebFrameTest
, DISABLED_DidAccessInitialDocumentBodyBeforeModalDialog
)
5561 TEST_P(ParameterizedWebFrameTest
, DidAccessInitialDocumentBodyBeforeModalDialog
)
5564 // FIXME: Why is this local webViewClient needed instead of the default
5565 // WebViewHelper one? With out it there's some mysterious crash in the
5566 // WebViewHelper destructor.
5567 FrameTestHelpers::TestWebViewClient webViewClient
;
5568 TestAccessInitialDocumentWebFrameClient webFrameClient
;
5569 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5570 webViewHelper
.initialize(true, &webFrameClient
, &webViewClient
);
5572 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5574 // Create another window that will try to access it.
5575 FrameTestHelpers::WebViewHelper
newWebViewHelper(this);
5576 WebView
* newView
= newWebViewHelper
.initialize(true);
5577 newView
->mainFrame()->setOpener(webViewHelper
.webView()->mainFrame());
5579 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5581 // Access the initial document by modifying the body. We normally set a
5582 // timer to notify the client.
5583 newView
->mainFrame()->executeScript(
5584 WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
5585 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5587 // Make sure that a modal dialog forces us to notify right away.
5588 newView
->mainFrame()->executeScript(
5589 WebScriptSource("window.opener.confirm('Modal');"));
5590 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5592 // Ensure that we don't notify again later.
5594 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5597 // Fails on the WebKit XP (deps) bot. http://crbug.com/312192
5599 TEST_P(ParameterizedWebFrameTest
, DISABLED_DidWriteToInitialDocumentBeforeModalDialog
)
5601 TEST_P(ParameterizedWebFrameTest
, DidWriteToInitialDocumentBeforeModalDialog
)
5604 // FIXME: Why is this local webViewClient needed instead of the default
5605 // WebViewHelper one? With out it there's some mysterious crash in the
5606 // WebViewHelper destructor.
5607 FrameTestHelpers::TestWebViewClient webViewClient
;
5608 TestAccessInitialDocumentWebFrameClient webFrameClient
;
5609 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5610 webViewHelper
.initialize(true, &webFrameClient
, &webViewClient
);
5612 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5614 // Create another window that will try to access it.
5615 FrameTestHelpers::WebViewHelper
newWebViewHelper(this);
5616 WebView
* newView
= newWebViewHelper
.initialize(true);
5617 newView
->mainFrame()->setOpener(webViewHelper
.webView()->mainFrame());
5619 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5621 // Access the initial document with document.write, which moves us past the
5622 // initial empty document state of the state machine. We normally set a
5623 // timer to notify the client.
5624 newView
->mainFrame()->executeScript(
5625 WebScriptSource("window.opener.document.write('Modified'); window.opener.document.close();"));
5626 EXPECT_FALSE(webFrameClient
.m_didAccessInitialDocument
);
5628 // Make sure that a modal dialog forces us to notify right away.
5629 newView
->mainFrame()->executeScript(
5630 WebScriptSource("window.opener.confirm('Modal');"));
5631 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5633 // Ensure that we don't notify again later.
5635 EXPECT_TRUE(webFrameClient
.m_didAccessInitialDocument
);
5638 class TestScrolledFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5640 TestScrolledFrameClient() { reset(); }
5643 m_didScrollFrame
= false;
5645 bool wasFrameScrolled() const { return m_didScrollFrame
; }
5648 void didChangeScrollOffset(WebLocalFrame
* frame
) override
5650 if (frame
->parent())
5652 EXPECT_FALSE(m_didScrollFrame
);
5653 FrameView
* view
= toWebLocalFrameImpl(frame
)->frameView();
5654 // FrameView can be scrolled in FrameView::setFixedVisibleContentRect
5655 // which is called from LocalFrame::createView (before the frame is associated
5656 // with the the view).
5658 m_didScrollFrame
= true;
5661 bool m_didScrollFrame
;
5664 TEST_F(WebFrameTest
, CompositorScrollIsUserScrollLongPage
)
5666 registerMockedHttpURLLoad("long_scroll.html");
5667 TestScrolledFrameClient client
;
5669 // Make sure we initialize to minimum scale, even if the window size
5670 // only becomes available after the load begins.
5671 FrameTestHelpers::WebViewHelper webViewHelper
;
5672 webViewHelper
.initializeAndLoad(m_baseURL
+ "long_scroll.html", true, &client
);
5673 webViewHelper
.webView()->resize(WebSize(1000, 1000));
5674 webViewHelper
.webView()->layout();
5676 WebLocalFrameImpl
* frameImpl
= webViewHelper
.webViewImpl()->mainFrameImpl();
5677 DocumentLoader::InitialScrollState
& initialScrollState
=
5678 frameImpl
->frame()->loader().documentLoader()->initialScrollState();
5680 EXPECT_FALSE(client
.wasFrameScrolled());
5681 EXPECT_FALSE(initialScrollState
.wasScrolledByUser
);
5683 // Do a compositor scroll, verify that this is counted as a user scroll.
5684 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(0, 1), WebFloatSize(), 1.7f
, 0);
5685 EXPECT_TRUE(client
.wasFrameScrolled());
5686 EXPECT_TRUE(initialScrollState
.wasScrolledByUser
);
5689 initialScrollState
.wasScrolledByUser
= false;
5691 // The page scale 1.0f and scroll.
5692 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(0, 1), WebFloatSize(), 1.0f
, 0);
5693 EXPECT_TRUE(client
.wasFrameScrolled());
5694 EXPECT_TRUE(initialScrollState
.wasScrolledByUser
);
5696 initialScrollState
.wasScrolledByUser
= false;
5698 // No scroll event if there is no scroll delta.
5699 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 0);
5700 EXPECT_FALSE(client
.wasFrameScrolled());
5701 EXPECT_FALSE(initialScrollState
.wasScrolledByUser
);
5704 // Non zero page scale and scroll.
5705 webViewHelper
.webViewImpl()->applyViewportDeltas(WebFloatSize(), WebFloatSize(9, 13), WebFloatSize(), 0.6f
, 0);
5706 EXPECT_TRUE(client
.wasFrameScrolled());
5707 EXPECT_TRUE(initialScrollState
.wasScrolledByUser
);
5709 initialScrollState
.wasScrolledByUser
= false;
5711 // Programmatic scroll.
5712 frameImpl
->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
5713 EXPECT_TRUE(client
.wasFrameScrolled());
5714 EXPECT_FALSE(initialScrollState
.wasScrolledByUser
);
5717 // Programmatic scroll to same offset. No scroll event should be generated.
5718 frameImpl
->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
5719 EXPECT_FALSE(client
.wasFrameScrolled());
5720 EXPECT_FALSE(initialScrollState
.wasScrolledByUser
);
5724 TEST_P(ParameterizedWebFrameTest
, FirstPartyForCookiesForRedirect
)
5726 WTF::String filePath
= Platform::current()->unitTestSupport()->webKitRootDir();
5727 filePath
.append("/Source/web/tests/data/first_party.html");
5729 WebURL
testURL(toKURL("http://internal.test/first_party_redirect.html"));
5730 char redirect
[] = "http://internal.test/first_party.html";
5731 WebURL
redirectURL(toKURL(redirect
));
5732 WebURLResponse redirectResponse
;
5733 redirectResponse
.initialize();
5734 redirectResponse
.setMIMEType("text/html");
5735 redirectResponse
.setHTTPStatusCode(302);
5736 redirectResponse
.setHTTPHeaderField("Location", redirect
);
5737 Platform::current()->unitTestSupport()->registerMockedURL(testURL
, redirectResponse
, filePath
);
5739 WebURLResponse finalResponse
;
5740 finalResponse
.initialize();
5741 finalResponse
.setMIMEType("text/html");
5742 Platform::current()->unitTestSupport()->registerMockedURL(redirectURL
, finalResponse
, filePath
);
5744 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5745 webViewHelper
.initializeAndLoad(m_baseURL
+ "first_party_redirect.html", true);
5746 EXPECT_TRUE(webViewHelper
.webView()->mainFrame()->document().firstPartyForCookies() == redirectURL
);
5749 class TestNavigationPolicyWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5752 void didNavigateWithinPage(WebLocalFrame
*, const WebHistoryItem
&, WebHistoryCommitType
) override
5758 TEST_P(ParameterizedWebFrameTest
, SimulateFragmentAnchorMiddleClick
)
5760 registerMockedHttpURLLoad("fragment_middle_click.html");
5761 TestNavigationPolicyWebFrameClient client
;
5762 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5763 webViewHelper
.initializeAndLoad(m_baseURL
+ "fragment_middle_click.html", true, &client
);
5765 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
5766 KURL destination
= document
->url();
5767 destination
.setFragmentIdentifier("test");
5769 RefPtrWillBeRawPtr
<Event
> event
= MouseEvent::create(EventTypeNames::click
, false, false,
5770 document
->domWindow(), 0, 0, 0, 0, 0, 0, 0, false, false, false, false, 1, 0, nullptr);
5771 FrameLoadRequest
frameRequest(document
, ResourceRequest(destination
));
5772 frameRequest
.setTriggeringEvent(event
);
5773 toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->loader().load(frameRequest
);
5776 class TestNewWindowWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
5778 virtual WebView
* createView(WebLocalFrame
*, const WebURLRequest
&, const WebWindowFeatures
&,
5779 const WebString
&, WebNavigationPolicy
, bool) override
5786 class TestNewWindowWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5788 TestNewWindowWebFrameClient()
5789 : m_decidePolicyCallCount(0)
5793 WebNavigationPolicy
decidePolicyForNavigation(const NavigationPolicyInfo
& info
) override
5795 m_decidePolicyCallCount
++;
5796 return info
.defaultPolicy
;
5799 int decidePolicyCallCount() const { return m_decidePolicyCallCount
; }
5802 int m_decidePolicyCallCount
;
5805 TEST_P(ParameterizedWebFrameTest
, ModifiedClickNewWindow
)
5807 registerMockedHttpURLLoad("ctrl_click.html");
5808 registerMockedHttpURLLoad("hello_world.html");
5809 TestNewWindowWebViewClient webViewClient
;
5810 TestNewWindowWebFrameClient webFrameClient
;
5811 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5812 webViewHelper
.initializeAndLoad(m_baseURL
+ "ctrl_click.html", true, &webFrameClient
, &webViewClient
);
5814 Document
* document
= toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document();
5815 KURL destination
= toKURL(m_baseURL
+ "hello_world.html");
5818 RefPtrWillBeRawPtr
<Event
> event
= MouseEvent::create(EventTypeNames::click
, false, false,
5819 document
->domWindow(), 0, 0, 0, 0, 0, 0, 0, true, false, false, false, 0, 0, nullptr);
5820 FrameLoadRequest
frameRequest(document
, ResourceRequest(destination
));
5821 frameRequest
.setTriggeringEvent(event
);
5822 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
5823 toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->loader().load(frameRequest
);
5824 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webView()->mainFrame());
5826 // decidePolicyForNavigation should be called both for the original request and the ctrl+click.
5827 EXPECT_EQ(2, webFrameClient
.decidePolicyCallCount());
5830 TEST_P(ParameterizedWebFrameTest
, BackToReload
)
5832 registerMockedHttpURLLoad("fragment_middle_click.html");
5833 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5834 webViewHelper
.initializeAndLoad(m_baseURL
+ "fragment_middle_click.html", true);
5835 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
5836 const FrameLoader
& mainFrameLoader
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame()->loader();
5837 RefPtrWillBePersistent
<HistoryItem
> firstItem
= mainFrameLoader
.currentItem();
5838 EXPECT_TRUE(firstItem
);
5840 registerMockedHttpURLLoad("white-1x1.png");
5841 FrameTestHelpers::loadFrame(frame
, m_baseURL
+ "white-1x1.png");
5842 EXPECT_NE(firstItem
.get(), mainFrameLoader
.currentItem());
5844 FrameTestHelpers::loadHistoryItem(frame
, WebHistoryItem(firstItem
.get()), WebHistoryDifferentDocumentLoad
, WebURLRequest::UseProtocolCachePolicy
);
5845 EXPECT_EQ(firstItem
.get(), mainFrameLoader
.currentItem());
5847 FrameTestHelpers::reloadFrame(frame
);
5848 EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData
, frame
->dataSource()->request().cachePolicy());
5851 TEST_P(ParameterizedWebFrameTest
, BackDuringChildFrameReload
)
5853 registerMockedHttpURLLoad("page_with_blank_iframe.html");
5854 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5855 webViewHelper
.initializeAndLoad(m_baseURL
+ "page_with_blank_iframe.html", true);
5856 WebFrame
* mainFrame
= webViewHelper
.webView()->mainFrame();
5857 const FrameLoader
& mainFrameLoader
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame()->loader();
5858 WebFrame
* childFrame
= mainFrame
->firstChild();
5859 ASSERT_TRUE(childFrame
);
5861 // Start a history navigation, then have a different frame commit a navigation.
5862 // In this case, reload an about:blank frame, which will commit synchronously.
5863 // After the history navigation completes, both the appropriate document url and
5864 // the current history item should reflect the history navigation.
5865 registerMockedHttpURLLoad("white-1x1.png");
5866 WebHistoryItem item
;
5868 WebURL
historyURL(toKURL(m_baseURL
+ "white-1x1.png"));
5869 item
.setURLString(historyURL
.string());
5870 mainFrame
->loadHistoryItem(item
, WebHistoryDifferentDocumentLoad
, WebURLRequest::UseProtocolCachePolicy
);
5872 FrameTestHelpers::reloadFrame(childFrame
);
5873 EXPECT_EQ(item
.urlString(), mainFrame
->document().url().string());
5874 EXPECT_EQ(item
.urlString(), WebString(mainFrameLoader
.currentItem()->urlString()));
5877 TEST_P(ParameterizedWebFrameTest
, ReloadPost
)
5879 registerMockedHttpURLLoad("reload_post.html");
5880 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5881 webViewHelper
.initializeAndLoad(m_baseURL
+ "reload_post.html", true);
5882 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
5884 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), "javascript:document.forms[0].submit()");
5885 // Pump requests one more time after the javascript URL has executed to
5886 // trigger the actual POST load request.
5887 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webView()->mainFrame());
5888 EXPECT_EQ(WebString::fromUTF8("POST"), frame
->dataSource()->request().httpMethod());
5890 FrameTestHelpers::reloadFrame(frame
);
5891 EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData
, frame
->dataSource()->request().cachePolicy());
5892 EXPECT_EQ(WebNavigationTypeFormResubmitted
, frame
->dataSource()->navigationType());
5895 TEST_P(ParameterizedWebFrameTest
, LoadHistoryItemReload
)
5897 registerMockedHttpURLLoad("fragment_middle_click.html");
5898 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5899 webViewHelper
.initializeAndLoad(m_baseURL
+ "fragment_middle_click.html", true);
5900 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
5901 const FrameLoader
& mainFrameLoader
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame()->loader();
5902 RefPtrWillBePersistent
<HistoryItem
> firstItem
= mainFrameLoader
.currentItem();
5903 EXPECT_TRUE(firstItem
);
5905 registerMockedHttpURLLoad("white-1x1.png");
5906 FrameTestHelpers::loadFrame(frame
, m_baseURL
+ "white-1x1.png");
5907 EXPECT_NE(firstItem
.get(), mainFrameLoader
.currentItem());
5909 // Cache policy overrides should take.
5910 FrameTestHelpers::loadHistoryItem(frame
, WebHistoryItem(firstItem
), WebHistoryDifferentDocumentLoad
, WebURLRequest::ReloadIgnoringCacheData
);
5911 EXPECT_EQ(firstItem
.get(), mainFrameLoader
.currentItem());
5912 EXPECT_EQ(WebURLRequest::ReloadIgnoringCacheData
, frame
->dataSource()->request().cachePolicy());
5916 class TestCachePolicyWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
5918 explicit TestCachePolicyWebFrameClient(TestCachePolicyWebFrameClient
* parentClient
)
5919 : m_parentClient(parentClient
)
5920 , m_policy(WebURLRequest::UseProtocolCachePolicy
)
5922 , m_willSendRequestCallCount(0)
5923 , m_childFrameCreationCount(0)
5927 void setChildWebFrameClient(TestCachePolicyWebFrameClient
* client
) { m_childClient
= client
; }
5928 WebURLRequest::CachePolicy
cachePolicy() const { return m_policy
; }
5929 int willSendRequestCallCount() const { return m_willSendRequestCallCount
; }
5930 int childFrameCreationCount() const { return m_childFrameCreationCount
; }
5932 virtual WebFrame
* createChildFrame(WebLocalFrame
* parent
, WebTreeScopeType scope
, const WebString
&, WebSandboxFlags
)
5934 ASSERT(m_childClient
);
5935 m_childFrameCreationCount
++;
5936 WebFrame
* frame
= WebLocalFrame::create(scope
, m_childClient
);
5937 parent
->appendChild(frame
);
5941 virtual void didStartLoading(bool toDifferentDocument
)
5943 if (m_parentClient
) {
5944 m_parentClient
->didStartLoading(toDifferentDocument
);
5947 TestWebFrameClient::didStartLoading(toDifferentDocument
);
5950 virtual void didStopLoading()
5952 if (m_parentClient
) {
5953 m_parentClient
->didStopLoading();
5956 TestWebFrameClient::didStopLoading();
5959 void willSendRequest(WebLocalFrame
* frame
, unsigned, WebURLRequest
& request
, const WebURLResponse
&) override
5961 m_policy
= request
.cachePolicy();
5962 m_willSendRequestCallCount
++;
5966 TestCachePolicyWebFrameClient
* m_parentClient
;
5968 WebURLRequest::CachePolicy m_policy
;
5969 TestCachePolicyWebFrameClient
* m_childClient
;
5970 int m_willSendRequestCallCount
;
5971 int m_childFrameCreationCount
;
5974 TEST_P(ParameterizedWebFrameTest
, ReloadIframe
)
5976 registerMockedHttpURLLoad("iframe_reload.html");
5977 registerMockedHttpURLLoad("visible_iframe.html");
5978 TestCachePolicyWebFrameClient
mainClient(0);
5979 TestCachePolicyWebFrameClient
childClient(&mainClient
);
5980 mainClient
.setChildWebFrameClient(&childClient
);
5982 FrameTestHelpers::WebViewHelper
webViewHelper(this);
5983 webViewHelper
.initializeAndLoad(m_baseURL
+ "iframe_reload.html", true, &mainClient
);
5985 WebLocalFrameImpl
* mainFrame
= webViewHelper
.webViewImpl()->mainFrameImpl();
5986 RefPtrWillBeRawPtr
<WebLocalFrameImpl
> childFrame
= toWebLocalFrameImpl(mainFrame
->firstChild());
5987 ASSERT_EQ(childFrame
->client(), &childClient
);
5988 EXPECT_EQ(mainClient
.childFrameCreationCount(), 1);
5989 EXPECT_EQ(childClient
.willSendRequestCallCount(), 1);
5990 EXPECT_EQ(childClient
.cachePolicy(), WebURLRequest::UseProtocolCachePolicy
);
5992 FrameTestHelpers::reloadFrame(mainFrame
);
5994 // A new WebFrame should have been created, but the child WebFrameClient should be reused.
5995 ASSERT_NE(childFrame
, toWebLocalFrameImpl(mainFrame
->firstChild()));
5996 ASSERT_EQ(toWebLocalFrameImpl(mainFrame
->firstChild())->client(), &childClient
);
5998 EXPECT_EQ(mainClient
.childFrameCreationCount(), 2);
5999 EXPECT_EQ(childClient
.willSendRequestCallCount(), 2);
6000 EXPECT_EQ(childClient
.cachePolicy(), WebURLRequest::ReloadIgnoringCacheData
);
6003 class TestSameDocumentWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6005 TestSameDocumentWebFrameClient()
6006 : m_frameLoadTypeSameSeen(false)
6010 virtual void willSendRequest(WebLocalFrame
* frame
, unsigned, WebURLRequest
&, const WebURLResponse
&)
6012 if (toWebLocalFrameImpl(frame
)->frame()->loader().loadType() == FrameLoadTypeSame
)
6013 m_frameLoadTypeSameSeen
= true;
6016 bool frameLoadTypeSameSeen() const { return m_frameLoadTypeSameSeen
; }
6019 bool m_frameLoadTypeSameSeen
;
6022 TEST_P(ParameterizedWebFrameTest
, NavigateToSame
)
6024 registerMockedHttpURLLoad("navigate_to_same.html");
6025 TestSameDocumentWebFrameClient client
;
6026 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6027 webViewHelper
.initializeAndLoad(m_baseURL
+ "navigate_to_same.html", true, &client
);
6028 EXPECT_FALSE(client
.frameLoadTypeSameSeen());
6030 FrameLoadRequest
frameRequest(0, ResourceRequest(toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->document()->url()));
6031 toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame())->loader().load(frameRequest
);
6032 FrameTestHelpers::pumpPendingRequestsDoNotUse(webViewHelper
.webView()->mainFrame());
6034 EXPECT_TRUE(client
.frameLoadTypeSameSeen());
6037 class TestSameDocumentWithImageWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6039 TestSameDocumentWithImageWebFrameClient()
6040 : m_numOfImageRequests(0)
6044 virtual void willSendRequest(WebLocalFrame
* frame
, unsigned, WebURLRequest
& request
, const WebURLResponse
&)
6046 if (request
.requestContext() == WebURLRequest::RequestContextImage
) {
6047 m_numOfImageRequests
++;
6048 EXPECT_EQ(WebURLRequest::UseProtocolCachePolicy
, request
.cachePolicy());
6052 int numOfImageRequests() const { return m_numOfImageRequests
; }
6055 int m_numOfImageRequests
;
6058 TEST_P(ParameterizedWebFrameTest
, NavigateToSameNoConditionalRequestForSubresource
)
6060 registerMockedHttpURLLoad("foo_with_image.html");
6061 registerMockedHttpURLLoad("white-1x1.png");
6062 TestSameDocumentWithImageWebFrameClient client
;
6063 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6064 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo_with_image.html", true, &client
, 0, &configureLoadsImagesAutomatically
);
6067 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "foo_with_image.html");
6069 EXPECT_EQ(client
.numOfImageRequests(), 2);
6072 TEST_P(ParameterizedWebFrameTest
, WebNodeImageContents
)
6074 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6075 webViewHelper
.initializeAndLoad("about:blank", true);
6076 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6078 static const char bluePNG
[] = "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYV2NkYPj/n4EIwDiqEF8oUT94AFIQE/cCn90IAAAAAElFTkSuQmCC\">";
6080 // Load up the image and test that we can extract the contents.
6081 KURL testURL
= toKURL("about:blank");
6082 FrameTestHelpers::loadHTMLString(frame
, bluePNG
, testURL
);
6084 WebNode node
= frame
->document().body().firstChild();
6085 EXPECT_TRUE(node
.isElementNode());
6086 WebElement element
= node
.to
<WebElement
>();
6087 WebImage image
= element
.imageContents();
6088 ASSERT_FALSE(image
.isNull());
6089 EXPECT_EQ(image
.size().width
, 10);
6090 EXPECT_EQ(image
.size().height
, 10);
6091 // FIXME: The rest of this test is disabled since the ImageDecodeCache state may be inconsistent when this test runs.
6093 // SkBitmap bitmap = image.getSkBitmap();
6094 // SkAutoLockPixels locker(bitmap);
6095 // EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorBLUE);
6098 class TestStartStopCallbackWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6100 TestStartStopCallbackWebFrameClient()
6101 : m_startLoadingCount(0)
6102 , m_stopLoadingCount(0)
6103 , m_differentDocumentStartCount(0)
6107 void didStartLoading(bool toDifferentDocument
) override
6109 TestWebFrameClient::didStartLoading(toDifferentDocument
);
6110 m_startLoadingCount
++;
6111 if (toDifferentDocument
)
6112 m_differentDocumentStartCount
++;
6115 void didStopLoading() override
6117 TestWebFrameClient::didStopLoading();
6118 m_stopLoadingCount
++;
6121 int startLoadingCount() const { return m_startLoadingCount
; }
6122 int stopLoadingCount() const { return m_stopLoadingCount
; }
6123 int differentDocumentStartCount() const { return m_differentDocumentStartCount
; }
6126 int m_startLoadingCount
;
6127 int m_stopLoadingCount
;
6128 int m_differentDocumentStartCount
;
6131 TEST_P(ParameterizedWebFrameTest
, PushStateStartsAndStops
)
6133 registerMockedHttpURLLoad("push_state.html");
6134 TestStartStopCallbackWebFrameClient client
;
6135 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6136 webViewHelper
.initializeAndLoad(m_baseURL
+ "push_state.html", true, &client
);
6138 EXPECT_EQ(client
.startLoadingCount(), 2);
6139 EXPECT_EQ(client
.stopLoadingCount(), 2);
6140 EXPECT_EQ(client
.differentDocumentStartCount(), 1);
6143 class TestDidNavigateCommitTypeWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6145 TestDidNavigateCommitTypeWebFrameClient()
6146 : m_lastCommitType(WebHistoryInertCommit
)
6150 void didNavigateWithinPage(WebLocalFrame
*, const WebHistoryItem
&, WebHistoryCommitType type
) override
6152 m_lastCommitType
= type
;
6155 WebHistoryCommitType
lastCommitType() const { return m_lastCommitType
; }
6158 WebHistoryCommitType m_lastCommitType
;
6161 TEST_P(ParameterizedWebFrameTest
, SameDocumentHistoryNavigationCommitType
)
6163 registerMockedHttpURLLoad("push_state.html");
6164 TestDidNavigateCommitTypeWebFrameClient client
;
6165 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6166 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "push_state.html", true, &client
);
6167 RefPtrWillBePersistent
<HistoryItem
> item
= toLocalFrame(webViewImpl
->page()->mainFrame())->loader().currentItem();
6170 toLocalFrame(webViewImpl
->page()->mainFrame())->loader().load(
6171 FrameLoadRequest(nullptr, FrameLoader::resourceRequestFromHistoryItem(
6172 item
.get(), UseProtocolCachePolicy
)),
6173 FrameLoadTypeBackForward
, item
.get(), HistorySameDocumentLoad
);
6174 EXPECT_EQ(WebBackForwardCommit
, client
.lastCommitType());
6177 class TestHistoryWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6179 TestHistoryWebFrameClient()
6181 m_replacesCurrentHistoryItem
= false;
6185 void didStartProvisionalLoad(WebLocalFrame
* frame
, double)
6187 WebDataSource
* ds
= frame
->provisionalDataSource();
6188 m_replacesCurrentHistoryItem
= ds
->replacesCurrentHistoryItem();
6192 bool replacesCurrentHistoryItem() { return m_replacesCurrentHistoryItem
; }
6193 WebFrame
* frame() { return m_frame
; }
6196 bool m_replacesCurrentHistoryItem
;
6200 // Tests that the first navigation in an initially blank subframe will result in
6201 // a history entry being replaced and not a new one being added.
6202 TEST_P(ParameterizedWebFrameTest
, FirstBlankSubframeNavigation
)
6204 registerMockedHttpURLLoad("history.html");
6205 registerMockedHttpURLLoad("find.html");
6207 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6208 TestHistoryWebFrameClient client
;
6209 webViewHelper
.initializeAndLoad("about:blank", true, &client
);
6211 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6213 frame
->executeScript(WebScriptSource(WebString::fromUTF8(
6214 "document.body.appendChild(document.createElement('iframe'))")));
6216 WebFrame
* iframe
= frame
->firstChild();
6217 ASSERT_EQ(&client
, toWebLocalFrameImpl(iframe
)->client());
6218 EXPECT_EQ(iframe
, client
.frame());
6220 std::string url1
= m_baseURL
+ "history.html";
6221 FrameTestHelpers::loadFrame(iframe
, url1
);
6222 EXPECT_EQ(iframe
, client
.frame());
6223 EXPECT_EQ(url1
, iframe
->document().url().string().utf8());
6224 EXPECT_TRUE(client
.replacesCurrentHistoryItem());
6226 std::string url2
= m_baseURL
+ "find.html";
6227 FrameTestHelpers::loadFrame(iframe
, url2
);
6228 EXPECT_EQ(iframe
, client
.frame());
6229 EXPECT_EQ(url2
, iframe
->document().url().string().utf8());
6230 EXPECT_FALSE(client
.replacesCurrentHistoryItem());
6233 // Tests that a navigation in a frame with a non-blank initial URL will create
6234 // a new history item, unlike the case above.
6235 TEST_P(ParameterizedWebFrameTest
, FirstNonBlankSubframeNavigation
)
6237 registerMockedHttpURLLoad("history.html");
6238 registerMockedHttpURLLoad("find.html");
6240 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6241 TestHistoryWebFrameClient client
;
6242 webViewHelper
.initializeAndLoad("about:blank", true, &client
);
6244 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6246 std::string url1
= m_baseURL
+ "history.html";
6247 FrameTestHelpers::loadFrame(frame
,
6248 "javascript:var f = document.createElement('iframe'); "
6249 "f.src = '" + url1
+ "';"
6250 "document.body.appendChild(f)");
6252 WebFrame
* iframe
= frame
->firstChild();
6253 EXPECT_EQ(iframe
, client
.frame());
6254 EXPECT_EQ(url1
, iframe
->document().url().string().utf8());
6256 std::string url2
= m_baseURL
+ "find.html";
6257 FrameTestHelpers::loadFrame(iframe
, url2
);
6258 EXPECT_EQ(iframe
, client
.frame());
6259 EXPECT_EQ(url2
, iframe
->document().url().string().utf8());
6260 EXPECT_FALSE(client
.replacesCurrentHistoryItem());
6263 // Test verifies that layout will change a layer's scrollable attibutes
6264 TEST_F(WebFrameTest
, overflowHiddenRewrite
)
6266 registerMockedHttpURLLoad("non-scrollable.html");
6267 OwnPtr
<FakeCompositingWebViewClient
> fakeCompositingWebViewClient
= adoptPtr(new FakeCompositingWebViewClient());
6268 FrameTestHelpers::WebViewHelper webViewHelper
;
6269 webViewHelper
.initialize(true, 0, fakeCompositingWebViewClient
.get(), &configueCompositingWebView
);
6271 webViewHelper
.webView()->resize(WebSize(100, 100));
6272 FrameTestHelpers::loadFrame(webViewHelper
.webView()->mainFrame(), m_baseURL
+ "non-scrollable.html");
6274 DeprecatedPaintLayerCompositor
* compositor
= webViewHelper
.webViewImpl()->compositor();
6275 ASSERT_TRUE(compositor
->scrollLayer());
6277 // Verify that the WebLayer is not scrollable initially.
6278 GraphicsLayer
* scrollLayer
= compositor
->scrollLayer();
6279 WebLayer
* webScrollLayer
= scrollLayer
->platformLayer();
6280 ASSERT_FALSE(webScrollLayer
->userScrollableHorizontal());
6281 ASSERT_FALSE(webScrollLayer
->userScrollableVertical());
6283 // Call javascript to make the layer scrollable, and verify it.
6284 WebLocalFrameImpl
* frame
= (WebLocalFrameImpl
*)webViewHelper
.webView()->mainFrame();
6285 frame
->executeScript(WebScriptSource("allowScroll();"));
6286 webViewHelper
.webView()->layout();
6287 ASSERT_TRUE(webScrollLayer
->userScrollableHorizontal());
6288 ASSERT_TRUE(webScrollLayer
->userScrollableVertical());
6291 // Test that currentHistoryItem reflects the current page, not the provisional load.
6292 TEST_P(ParameterizedWebFrameTest
, CurrentHistoryItem
)
6294 registerMockedHttpURLLoad("fixed_layout.html");
6295 std::string url
= m_baseURL
+ "fixed_layout.html";
6297 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6298 webViewHelper
.initialize();
6299 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6300 const FrameLoader
& mainFrameLoader
= webViewHelper
.webViewImpl()->mainFrameImpl()->frame()->loader();
6301 WebURLRequest request
;
6302 request
.initialize();
6303 request
.setURL(toKURL(url
));
6304 frame
->loadRequest(request
);
6306 // Before commit, there is no history item.
6307 EXPECT_FALSE(mainFrameLoader
.currentItem());
6309 FrameTestHelpers::pumpPendingRequestsDoNotUse(frame
);
6311 // After commit, there is.
6312 HistoryItem
* item
= mainFrameLoader
.currentItem();
6314 EXPECT_EQ(WTF::String(url
.data()), item
->urlString());
6317 class FailCreateChildFrame
: public FrameTestHelpers::TestWebFrameClient
{
6319 FailCreateChildFrame() : m_callCount(0) { }
6321 WebFrame
* createChildFrame(WebLocalFrame
* parent
, WebTreeScopeType scope
, const WebString
& frameName
, WebSandboxFlags sandboxFlags
) override
6327 int callCount() const { return m_callCount
; }
6333 // Test that we don't crash if WebFrameClient::createChildFrame() fails.
6334 TEST_P(ParameterizedWebFrameTest
, CreateChildFrameFailure
)
6336 registerMockedHttpURLLoad("create_child_frame_fail.html");
6337 FailCreateChildFrame client
;
6338 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6339 webViewHelper
.initializeAndLoad(m_baseURL
+ "create_child_frame_fail.html", true, &client
);
6341 EXPECT_EQ(1, client
.callCount());
6344 TEST_P(ParameterizedWebFrameTest
, fixedPositionInFixedViewport
)
6346 UseMockScrollbarSettings mockScrollbarSettings
;
6347 registerMockedHttpURLLoad("fixed-position-in-fixed-viewport.html");
6348 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6349 webViewHelper
.initializeAndLoad(m_baseURL
+ "fixed-position-in-fixed-viewport.html", true, 0, 0, enableViewportSettings
);
6351 WebView
* webView
= webViewHelper
.webView();
6352 webView
->resize(WebSize(100, 100));
6354 Document
* document
= toWebLocalFrameImpl(webView
->mainFrame())->frame()->document();
6355 Element
* bottomFixed
= document
->getElementById("bottom-fixed");
6356 Element
* topBottomFixed
= document
->getElementById("top-bottom-fixed");
6357 Element
* rightFixed
= document
->getElementById("right-fixed");
6358 Element
* leftRightFixed
= document
->getElementById("left-right-fixed");
6360 // The layout viewport will hit the min-scale limit of 0.25, so it'll be 400x800.
6361 webView
->resize(WebSize(100, 200));
6362 EXPECT_EQ(800, bottomFixed
->offsetTop() + bottomFixed
->offsetHeight());
6363 EXPECT_EQ(800, topBottomFixed
->offsetHeight());
6365 // Now the layout viewport hits the content width limit of 500px so it'll be 500x500.
6366 webView
->resize(WebSize(200, 200));
6367 EXPECT_EQ(500, rightFixed
->offsetLeft() + rightFixed
->offsetWidth());
6368 EXPECT_EQ(500, leftRightFixed
->offsetWidth());
6371 TEST_P(ParameterizedWebFrameTest
, FrameViewMoveWithSetFrameRect
)
6373 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6374 webViewHelper
.initializeAndLoad("about:blank");
6375 webViewHelper
.webViewImpl()->resize(WebSize(200, 200));
6376 webViewHelper
.webViewImpl()->layout();
6378 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
6379 EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), frameView
->frameRect());
6380 frameView
->setFrameRect(IntRect(100, 100, 200, 200));
6381 EXPECT_RECT_EQ(IntRect(100, 100, 200, 200), frameView
->frameRect());
6384 TEST_F(WebFrameTest
, FrameViewScrollAccountsForTopControls
)
6386 FakeCompositingWebViewClient client
;
6387 registerMockedHttpURLLoad("long_scroll.html");
6388 UseMockScrollbarSettings mockScrollbarSettings
;
6389 FrameTestHelpers::WebViewHelper webViewHelper
;
6390 webViewHelper
.initializeAndLoad(m_baseURL
+ "long_scroll.html", true, 0, &client
, configureAndroid
);
6392 WebViewImpl
* webView
= webViewHelper
.webViewImpl();
6393 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
6395 float topControlsHeight
= 40;
6396 webView
->setTopControlsHeight(topControlsHeight
, false);
6397 webView
->resize(WebSize(100, 100));
6398 webView
->setPageScaleFactor(2.0f
);
6401 webView
->mainFrame()->setScrollOffset(WebSize(0, 2000));
6402 EXPECT_POINT_EQ(IntPoint(0, 1900), IntPoint(frameView
->scrollOffset()));
6404 // Simulate the top controls showing by 20px, thus shrinking the viewport
6405 // and allowing it to scroll an additional 20px.
6406 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 20.0f
/ topControlsHeight
);
6407 EXPECT_POINT_EQ(IntPoint(0, 1920), frameView
->maximumScrollPosition());
6409 // Show more, make sure the scroll actually gets clamped.
6410 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 20.0f
/ topControlsHeight
);
6411 webView
->mainFrame()->setScrollOffset(WebSize(0, 2000));
6412 EXPECT_POINT_EQ(IntPoint(0, 1940), IntPoint(frameView
->scrollOffset()));
6414 // Hide until there's 10px showing.
6415 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, -30.0f
/ topControlsHeight
);
6416 EXPECT_POINT_EQ(IntPoint(0, 1910), frameView
->maximumScrollPosition());
6418 // Simulate a LayoutPart::resize. The frame is resized to accomodate
6419 // the top controls and Blink's view of the top controls matches that of
6421 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 30.0f
/ topControlsHeight
);
6422 webView
->setTopControlsHeight(40.0f
, true);
6423 webView
->resize(WebSize(100, 60));
6425 EXPECT_POINT_EQ(IntPoint(0, 1940), frameView
->maximumScrollPosition());
6427 // Now simulate hiding.
6428 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, -10.0f
/ topControlsHeight
);
6429 EXPECT_POINT_EQ(IntPoint(0, 1930), frameView
->maximumScrollPosition());
6431 // Reset to original state: 100px widget height, top controls fully hidden.
6432 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, -30.0f
/ topControlsHeight
);
6433 webView
->setTopControlsHeight(topControlsHeight
, false);
6434 webView
->resize(WebSize(100, 100));
6436 EXPECT_POINT_EQ(IntPoint(0, 1900), frameView
->maximumScrollPosition());
6438 // Show the top controls by just 1px, since we're zoomed in to 2X, that
6439 // should allow an extra 0.5px of scrolling in the visual viewport. Make
6440 // sure we're not losing any pixels when applying the adjustment on the
6442 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 1.0f
/ topControlsHeight
);
6443 EXPECT_POINT_EQ(IntPoint(0, 1901), frameView
->maximumScrollPosition());
6445 webView
->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(), 1.0f
, 2.0f
/ topControlsHeight
);
6446 EXPECT_POINT_EQ(IntPoint(0, 1903), frameView
->maximumScrollPosition());
6449 TEST_F(WebFrameTest
, MaximumScrollPositionCanBeNegative
)
6451 UseMockScrollbarSettings mockScrollbarSettings
;
6452 registerMockedHttpURLLoad("rtl-overview-mode.html");
6454 FixedLayoutTestWebViewClient client
;
6455 client
.m_screenInfo
.deviceScaleFactor
= 1;
6456 int viewportWidth
= 640;
6457 int viewportHeight
= 480;
6459 FrameTestHelpers::WebViewHelper webViewHelper
;
6460 webViewHelper
.initializeAndLoad(m_baseURL
+ "rtl-overview-mode.html", true, 0, &client
, enableViewportSettings
);
6461 webViewHelper
.webView()->setInitialPageScaleOverride(-1);
6462 webViewHelper
.webView()->settings()->setWideViewportQuirkEnabled(true);
6463 webViewHelper
.webView()->settings()->setLoadWithOverviewMode(true);
6464 webViewHelper
.webView()->settings()->setUseWideViewport(true);
6465 webViewHelper
.webView()->resize(WebSize(viewportWidth
, viewportHeight
));
6466 webViewHelper
.webView()->layout();
6468 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
6469 EXPECT_LT(frameView
->maximumScrollPosition().x(), 0);
6472 TEST_P(ParameterizedWebFrameTest
, FullscreenLayerSize
)
6474 FakeCompositingWebViewClient client
;
6475 registerMockedHttpURLLoad("fullscreen_div.html");
6476 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6477 int viewportWidth
= 640;
6478 int viewportHeight
= 480;
6479 client
.m_screenInfo
.rect
.width
= viewportWidth
;
6480 client
.m_screenInfo
.rect
.height
= viewportHeight
;
6481 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "fullscreen_div.html", true, 0, &client
, configureAndroid
);
6482 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6483 webViewImpl
->layout();
6485 Document
* document
= toWebLocalFrameImpl(webViewImpl
->mainFrame())->frame()->document();
6486 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6487 Element
* divFullscreen
= document
->getElementById("div1");
6488 Fullscreen::from(*document
).requestFullscreen(*divFullscreen
, Fullscreen::PrefixedRequest
);
6489 webViewImpl
->didEnterFullScreen();
6490 webViewImpl
->layout();
6491 ASSERT_TRUE(Fullscreen::isFullScreen(*document
));
6493 // Verify that the element is sized to the viewport.
6494 LayoutFullScreen
* fullscreenLayoutObject
= Fullscreen::from(*document
).fullScreenLayoutObject();
6495 EXPECT_EQ(viewportWidth
, fullscreenLayoutObject
->logicalWidth().toInt());
6496 EXPECT_EQ(viewportHeight
, fullscreenLayoutObject
->logicalHeight().toInt());
6498 // Verify it's updated after a device rotation.
6499 client
.m_screenInfo
.rect
.width
= viewportHeight
;
6500 client
.m_screenInfo
.rect
.height
= viewportWidth
;
6501 webViewImpl
->resize(WebSize(viewportHeight
, viewportWidth
));
6502 webViewImpl
->layout();
6503 EXPECT_EQ(viewportHeight
, fullscreenLayoutObject
->logicalWidth().toInt());
6504 EXPECT_EQ(viewportWidth
, fullscreenLayoutObject
->logicalHeight().toInt());
6507 TEST_F(WebFrameTest
, FullscreenLayerNonScrollable
)
6509 FakeCompositingWebViewClient client
;
6510 registerMockedHttpURLLoad("fullscreen_div.html");
6511 FrameTestHelpers::WebViewHelper webViewHelper
;
6512 int viewportWidth
= 640;
6513 int viewportHeight
= 480;
6514 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "fullscreen_div.html", true, 0, &client
, configureAndroid
);
6515 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6516 webViewImpl
->layout();
6518 Document
* document
= toWebLocalFrameImpl(webViewImpl
->mainFrame())->frame()->document();
6519 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6520 Element
* divFullscreen
= document
->getElementById("div1");
6521 Fullscreen::from(*document
).requestFullscreen(*divFullscreen
, Fullscreen::PrefixedRequest
);
6522 webViewImpl
->didEnterFullScreen();
6523 webViewImpl
->layout();
6525 // Verify that the viewports are nonscrollable.
6526 ASSERT_TRUE(Fullscreen::isFullScreen(*document
));
6527 FrameView
* frameView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView();
6528 WebLayer
* layoutViewportScrollLayer
= webViewImpl
->compositor()->scrollLayer()->platformLayer();
6529 WebLayer
* visualViewportScrollLayer
= frameView
->page()->frameHost().visualViewport().scrollLayer()->platformLayer();
6530 ASSERT_FALSE(layoutViewportScrollLayer
->userScrollableHorizontal());
6531 ASSERT_FALSE(layoutViewportScrollLayer
->userScrollableVertical());
6532 ASSERT_FALSE(visualViewportScrollLayer
->userScrollableHorizontal());
6533 ASSERT_FALSE(visualViewportScrollLayer
->userScrollableVertical());
6535 // Verify that the viewports are scrollable upon exiting fullscreen.
6536 webViewImpl
->didExitFullScreen();
6537 webViewImpl
->layout();
6538 ASSERT_FALSE(Fullscreen::isFullScreen(*document
));
6539 ASSERT_TRUE(layoutViewportScrollLayer
->userScrollableHorizontal());
6540 ASSERT_TRUE(layoutViewportScrollLayer
->userScrollableVertical());
6541 ASSERT_TRUE(visualViewportScrollLayer
->userScrollableHorizontal());
6542 ASSERT_TRUE(visualViewportScrollLayer
->userScrollableVertical());
6545 TEST_P(ParameterizedWebFrameTest
, FullscreenMainFrame
)
6547 FakeCompositingWebViewClient client
;
6548 registerMockedHttpURLLoad("fullscreen_div.html");
6549 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6550 int viewportWidth
= 640;
6551 int viewportHeight
= 480;
6552 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "fullscreen_div.html", true, 0, &client
, configureAndroid
);
6553 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6554 webViewImpl
->layout();
6556 Document
* document
= toWebLocalFrameImpl(webViewImpl
->mainFrame())->frame()->document();
6557 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6558 Fullscreen::from(*document
).requestFullscreen(*document
->documentElement(), Fullscreen::PrefixedRequest
);
6559 webViewImpl
->didEnterFullScreen();
6560 webViewImpl
->layout();
6562 // Verify that the main frame is still scrollable.
6563 ASSERT_TRUE(Fullscreen::isFullScreen(*document
));
6564 WebLayer
* webScrollLayer
= webViewImpl
->compositor()->scrollLayer()->platformLayer();
6565 ASSERT_TRUE(webScrollLayer
->scrollable());
6566 ASSERT_TRUE(webScrollLayer
->userScrollableHorizontal());
6567 ASSERT_TRUE(webScrollLayer
->userScrollableVertical());
6569 // Verify the main frame still behaves correctly after a resize.
6570 webViewImpl
->resize(WebSize(viewportHeight
, viewportWidth
));
6571 ASSERT_TRUE(webScrollLayer
->scrollable());
6572 ASSERT_TRUE(webScrollLayer
->userScrollableHorizontal());
6573 ASSERT_TRUE(webScrollLayer
->userScrollableVertical());
6576 TEST_P(ParameterizedWebFrameTest
, FullscreenSubframe
)
6578 FakeCompositingWebViewClient client
;
6579 registerMockedHttpURLLoad("fullscreen_iframe.html");
6580 registerMockedHttpURLLoad("fullscreen_div.html");
6581 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6582 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "fullscreen_iframe.html", true, 0, &client
, configureAndroid
);
6583 int viewportWidth
= 640;
6584 int viewportHeight
= 480;
6585 client
.m_screenInfo
.rect
.width
= viewportWidth
;
6586 client
.m_screenInfo
.rect
.height
= viewportHeight
;
6587 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6588 webViewImpl
->layout();
6590 Document
* document
= toWebLocalFrameImpl(webViewHelper
.webView()->mainFrame()->firstChild())->frame()->document();
6591 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6592 Element
* divFullscreen
= document
->getElementById("div1");
6593 Fullscreen::from(*document
).requestFullscreen(*divFullscreen
, Fullscreen::PrefixedRequest
);
6594 webViewImpl
->didEnterFullScreen();
6595 webViewImpl
->layout();
6597 // Verify that the element is sized to the viewport.
6598 LayoutFullScreen
* fullscreenLayoutObject
= Fullscreen::from(*document
).fullScreenLayoutObject();
6599 EXPECT_EQ(viewportWidth
, fullscreenLayoutObject
->logicalWidth().toInt());
6600 EXPECT_EQ(viewportHeight
, fullscreenLayoutObject
->logicalHeight().toInt());
6602 // Verify it's updated after a device rotation.
6603 client
.m_screenInfo
.rect
.width
= viewportHeight
;
6604 client
.m_screenInfo
.rect
.height
= viewportWidth
;
6605 webViewImpl
->resize(WebSize(viewportHeight
, viewportWidth
));
6606 webViewImpl
->layout();
6607 EXPECT_EQ(viewportHeight
, fullscreenLayoutObject
->logicalWidth().toInt());
6608 EXPECT_EQ(viewportWidth
, fullscreenLayoutObject
->logicalHeight().toInt());
6611 TEST_P(ParameterizedWebFrameTest
, FullscreenWithTinyViewport
)
6613 FakeCompositingWebViewClient client
;
6614 registerMockedHttpURLLoad("viewport-tiny.html");
6615 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6616 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-tiny.html", true, 0, &client
, configureAndroid
);
6617 int viewportWidth
= 384;
6618 int viewportHeight
= 640;
6619 client
.m_screenInfo
.rect
.width
= viewportWidth
;
6620 client
.m_screenInfo
.rect
.height
= viewportHeight
;
6621 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6622 webViewImpl
->layout();
6624 LayoutView
* layoutView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutView();
6625 EXPECT_EQ(320, layoutView
->logicalWidth().floor());
6626 EXPECT_EQ(533, layoutView
->logicalHeight().floor());
6627 EXPECT_FLOAT_EQ(1.2, webViewImpl
->pageScaleFactor());
6628 EXPECT_FLOAT_EQ(1.2, webViewImpl
->minimumPageScaleFactor());
6629 EXPECT_FLOAT_EQ(5.0, webViewImpl
->maximumPageScaleFactor());
6631 Document
* document
= toWebLocalFrameImpl(webViewImpl
->mainFrame())->frame()->document();
6632 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6633 Fullscreen::from(*document
).requestFullscreen(*document
->documentElement(), Fullscreen::PrefixedRequest
);
6634 webViewImpl
->didEnterFullScreen();
6635 webViewImpl
->layout();
6636 EXPECT_EQ(384, layoutView
->logicalWidth().floor());
6637 EXPECT_EQ(640, layoutView
->logicalHeight().floor());
6638 EXPECT_FLOAT_EQ(1.0, webViewImpl
->pageScaleFactor());
6639 EXPECT_FLOAT_EQ(1.0, webViewImpl
->minimumPageScaleFactor());
6640 EXPECT_FLOAT_EQ(1.0, webViewImpl
->maximumPageScaleFactor());
6642 webViewImpl
->didExitFullScreen();
6643 webViewImpl
->layout();
6644 EXPECT_EQ(320, layoutView
->logicalWidth().floor());
6645 EXPECT_EQ(533, layoutView
->logicalHeight().floor());
6646 EXPECT_FLOAT_EQ(1.2, webViewImpl
->pageScaleFactor());
6647 EXPECT_FLOAT_EQ(1.2, webViewImpl
->minimumPageScaleFactor());
6648 EXPECT_FLOAT_EQ(5.0, webViewImpl
->maximumPageScaleFactor());
6651 TEST_P(ParameterizedWebFrameTest
, FullscreenResizeWithTinyViewport
)
6653 FakeCompositingWebViewClient client
;
6654 registerMockedHttpURLLoad("viewport-tiny.html");
6655 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6656 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "viewport-tiny.html", true, 0, &client
, configureAndroid
);
6657 int viewportWidth
= 384;
6658 int viewportHeight
= 640;
6659 client
.m_screenInfo
.rect
.width
= viewportWidth
;
6660 client
.m_screenInfo
.rect
.height
= viewportHeight
;
6661 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6662 webViewImpl
->layout();
6664 LayoutView
* layoutView
= webViewHelper
.webViewImpl()->mainFrameImpl()->frameView()->layoutView();
6665 Document
* document
= toWebLocalFrameImpl(webViewImpl
->mainFrame())->frame()->document();
6666 UserGestureIndicator
gesture(DefinitelyProcessingUserGesture
);
6667 Fullscreen::from(*document
).requestFullscreen(*document
->documentElement(), Fullscreen::PrefixedRequest
);
6668 webViewImpl
->didEnterFullScreen();
6669 webViewImpl
->layout();
6670 EXPECT_EQ(384, layoutView
->logicalWidth().floor());
6671 EXPECT_EQ(640, layoutView
->logicalHeight().floor());
6672 EXPECT_FLOAT_EQ(1.0, webViewImpl
->pageScaleFactor());
6673 EXPECT_FLOAT_EQ(1.0, webViewImpl
->minimumPageScaleFactor());
6674 EXPECT_FLOAT_EQ(1.0, webViewImpl
->maximumPageScaleFactor());
6676 viewportWidth
= 640;
6677 viewportHeight
= 384;
6678 client
.m_screenInfo
.rect
.width
= viewportWidth
;
6679 client
.m_screenInfo
.rect
.height
= viewportHeight
;
6680 webViewImpl
->resize(WebSize(viewportWidth
, viewportHeight
));
6681 webViewImpl
->layout();
6682 EXPECT_EQ(640, layoutView
->logicalWidth().floor());
6683 EXPECT_EQ(384, layoutView
->logicalHeight().floor());
6684 EXPECT_FLOAT_EQ(1.0, webViewImpl
->pageScaleFactor());
6685 EXPECT_FLOAT_EQ(1.0, webViewImpl
->minimumPageScaleFactor());
6686 EXPECT_FLOAT_EQ(1.0, webViewImpl
->maximumPageScaleFactor());
6688 webViewImpl
->didExitFullScreen();
6689 webViewImpl
->layout();
6690 EXPECT_EQ(320, layoutView
->logicalWidth().floor());
6691 EXPECT_EQ(192, layoutView
->logicalHeight().floor());
6692 EXPECT_FLOAT_EQ(2, webViewImpl
->pageScaleFactor());
6693 EXPECT_FLOAT_EQ(2, webViewImpl
->minimumPageScaleFactor());
6694 EXPECT_FLOAT_EQ(5.0, webViewImpl
->maximumPageScaleFactor());
6697 TEST_P(ParameterizedWebFrameTest
, LayoutBlockPercentHeightDescendants
)
6699 registerMockedHttpURLLoad("percent-height-descendants.html");
6700 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6701 webViewHelper
.initializeAndLoad(m_baseURL
+ "percent-height-descendants.html");
6703 WebView
* webView
= webViewHelper
.webView();
6704 webView
->resize(WebSize(800, 800));
6707 Document
* document
= toWebLocalFrameImpl(webView
->mainFrame())->frame()->document();
6708 LayoutBlock
* container
= toLayoutBlock(document
->getElementById("container")->layoutObject());
6709 LayoutBox
* percentHeightInAnonymous
= toLayoutBox(document
->getElementById("percent-height-in-anonymous")->layoutObject());
6710 LayoutBox
* percentHeightDirectChild
= toLayoutBox(document
->getElementById("percent-height-direct-child")->layoutObject());
6712 EXPECT_TRUE(LayoutBlock::hasPercentHeightDescendant(percentHeightInAnonymous
));
6713 EXPECT_TRUE(LayoutBlock::hasPercentHeightDescendant(percentHeightDirectChild
));
6715 ASSERT_TRUE(container
->percentHeightDescendants());
6716 ASSERT_TRUE(container
->hasPercentHeightDescendants());
6717 EXPECT_EQ(2U, container
->percentHeightDescendants()->size());
6718 EXPECT_TRUE(container
->percentHeightDescendants()->contains(percentHeightInAnonymous
));
6719 EXPECT_TRUE(container
->percentHeightDescendants()->contains(percentHeightDirectChild
));
6721 LayoutBlock
* anonymousBlock
= percentHeightInAnonymous
->containingBlock();
6722 EXPECT_TRUE(anonymousBlock
->isAnonymous());
6723 EXPECT_FALSE(anonymousBlock
->hasPercentHeightDescendants());
6726 TEST_P(ParameterizedWebFrameTest
, HasVisibleContentOnVisibleFrames
)
6728 registerMockedHttpURLLoad("visible_frames.html");
6729 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6730 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "visible_frames.html");
6731 for (WebFrame
* frame
= webViewImpl
->mainFrameImpl()->traverseNext(false); frame
; frame
= frame
->traverseNext(false)) {
6732 EXPECT_TRUE(frame
->hasVisibleContent());
6736 TEST_P(ParameterizedWebFrameTest
, HasVisibleContentOnHiddenFrames
)
6738 registerMockedHttpURLLoad("hidden_frames.html");
6739 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6740 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "hidden_frames.html");
6741 for (WebFrame
* frame
= webViewImpl
->mainFrameImpl()->traverseNext(false); frame
; frame
= frame
->traverseNext(false)) {
6742 EXPECT_FALSE(frame
->hasVisibleContent());
6746 class ManifestChangeWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6748 ManifestChangeWebFrameClient() : m_manifestChangeCount(0) { }
6749 void didChangeManifest(WebLocalFrame
*) override
6751 ++m_manifestChangeCount
;
6754 int manifestChangeCount() { return m_manifestChangeCount
; }
6757 int m_manifestChangeCount
;
6760 TEST_P(ParameterizedWebFrameTest
, NotifyManifestChange
)
6762 registerMockedHttpURLLoad("link-manifest-change.html");
6764 ManifestChangeWebFrameClient webFrameClient
;
6765 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6766 webViewHelper
.initializeAndLoad(m_baseURL
+ "link-manifest-change.html", true, &webFrameClient
);
6768 EXPECT_EQ(14, webFrameClient
.manifestChangeCount());
6771 static ResourcePtr
<Resource
> fetchManifest(Document
* document
, const KURL
& url
)
6773 FetchRequest fetchRequest
= FetchRequest(ResourceRequest(url
), FetchInitiatorInfo());
6774 fetchRequest
.mutableResourceRequest().setRequestContext(WebURLRequest::RequestContextManifest
);
6776 return RawResource::fetchSynchronously(fetchRequest
, document
->fetcher());
6779 TEST_P(ParameterizedWebFrameTest
, ManifestFetch
)
6781 registerMockedHttpURLLoad("foo.html");
6782 registerMockedHttpURLLoad("link-manifest-fetch.json");
6784 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6785 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html");
6786 Document
* document
= toWebLocalFrameImpl(webViewHelper
.webViewImpl()->mainFrame())->frame()->document();
6788 ResourcePtr
<Resource
> resource
= fetchManifest(document
, toKURL(m_baseURL
+ "link-manifest-fetch.json"));
6790 EXPECT_TRUE(resource
->isLoaded());
6793 TEST_P(ParameterizedWebFrameTest
, ManifestCSPFetchAllow
)
6795 URLTestHelpers::registerMockedURLLoad(toKURL(m_notBaseURL
+ "link-manifest-fetch.json"), "link-manifest-fetch.json");
6796 registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src *");
6798 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6799 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html");
6800 Document
* document
= toWebLocalFrameImpl(webViewHelper
.webViewImpl()->mainFrame())->frame()->document();
6802 ResourcePtr
<Resource
> resource
= fetchManifest(document
, toKURL(m_notBaseURL
+ "link-manifest-fetch.json"));
6804 EXPECT_TRUE(resource
->isLoaded());
6807 TEST_P(ParameterizedWebFrameTest
, ManifestCSPFetchSelf
)
6809 URLTestHelpers::registerMockedURLLoad(toKURL(m_notBaseURL
+ "link-manifest-fetch.json"), "link-manifest-fetch.json");
6810 registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src 'self'");
6812 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6813 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html");
6814 Document
* document
= toWebLocalFrameImpl(webViewHelper
.webViewImpl()->mainFrame())->frame()->document();
6816 ResourcePtr
<Resource
> resource
= fetchManifest(document
, toKURL(m_notBaseURL
+ "link-manifest-fetch.json"));
6818 EXPECT_EQ(0, resource
.get()); // Fetching resource wasn't allowed.
6821 TEST_P(ParameterizedWebFrameTest
, ManifestCSPFetchSelfReportOnly
)
6823 URLTestHelpers::registerMockedURLLoad(toKURL(m_notBaseURL
+ "link-manifest-fetch.json"), "link-manifest-fetch.json");
6824 registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src 'self'", /* report only */ true);
6826 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6827 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html");
6828 Document
* document
= toWebLocalFrameImpl(webViewHelper
.webViewImpl()->mainFrame())->frame()->document();
6830 ResourcePtr
<Resource
> resource
= fetchManifest(document
, toKURL(m_notBaseURL
+ "link-manifest-fetch.json"));
6832 EXPECT_TRUE(resource
->isLoaded());
6835 TEST_P(ParameterizedWebFrameTest
, ReloadBypassingCache
)
6837 // Check that a reload ignoring cache on a frame will result in the cache
6838 // policy of the request being set to ReloadBypassingCache.
6839 registerMockedHttpURLLoad("foo.html");
6840 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6841 webViewHelper
.initializeAndLoad(m_baseURL
+ "foo.html", true);
6842 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6843 FrameTestHelpers::reloadFrameIgnoringCache(frame
);
6844 EXPECT_EQ(WebURLRequest::ReloadBypassingCache
, frame
->dataSource()->request().cachePolicy());
6847 static void nodeImageTestValidation(const IntSize
& referenceBitmapSize
, DragImage
* dragImage
)
6849 // Prepare the reference bitmap.
6851 bitmap
.allocN32Pixels(referenceBitmapSize
.width(), referenceBitmapSize
.height());
6852 SkCanvas
canvas(bitmap
);
6853 canvas
.drawColor(SK_ColorGREEN
);
6855 EXPECT_EQ(referenceBitmapSize
.width(), dragImage
->size().width());
6856 EXPECT_EQ(referenceBitmapSize
.height(), dragImage
->size().height());
6857 const SkBitmap
& dragBitmap
= dragImage
->bitmap();
6858 SkAutoLockPixels
lockPixel(dragBitmap
);
6859 EXPECT_EQ(0, memcmp(bitmap
.getPixels(), dragBitmap
.getPixels(), bitmap
.getSize()));
6862 TEST_P(ParameterizedWebFrameTest
, NodeImageTestCSSTransform
)
6864 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6865 OwnPtr
<DragImage
> dragImage
= nodeImageTestSetup(&webViewHelper
, std::string("case-css-transform"));
6866 EXPECT_TRUE(dragImage
);
6868 nodeImageTestValidation(IntSize(40, 40), dragImage
.get());
6871 TEST_P(ParameterizedWebFrameTest
, NodeImageTestCSS3DTransform
)
6873 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6874 OwnPtr
<DragImage
> dragImage
= nodeImageTestSetup(&webViewHelper
, std::string("case-css-3dtransform"));
6875 EXPECT_TRUE(dragImage
);
6877 nodeImageTestValidation(IntSize(20, 40), dragImage
.get());
6880 TEST_P(ParameterizedWebFrameTest
, NodeImageTestInlineBlock
)
6882 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6883 OwnPtr
<DragImage
> dragImage
= nodeImageTestSetup(&webViewHelper
, std::string("case-inlineblock"));
6884 EXPECT_TRUE(dragImage
);
6886 nodeImageTestValidation(IntSize(40, 40), dragImage
.get());
6889 TEST_P(ParameterizedWebFrameTest
, NodeImageTestFloatLeft
)
6891 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6892 OwnPtr
<DragImage
> dragImage
= nodeImageTestSetup(&webViewHelper
, std::string("case-float-left-overflow-hidden"));
6893 EXPECT_TRUE(dragImage
);
6895 nodeImageTestValidation(IntSize(40, 40), dragImage
.get());
6898 // Crashes on Android: http://crbug.com/403804
6900 TEST_P(ParameterizedWebFrameTest
, DISABLED_PrintingBasic
)
6902 TEST_P(ParameterizedWebFrameTest
, PrintingBasic
)
6905 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6906 webViewHelper
.initializeAndLoad("data:text/html,Hello, world.");
6908 WebFrame
* frame
= webViewHelper
.webView()->mainFrame();
6910 WebPrintParams printParams
;
6911 printParams
.printContentArea
.width
= 500;
6912 printParams
.printContentArea
.height
= 500;
6914 int pageCount
= frame
->printBegin(printParams
);
6915 EXPECT_EQ(1, pageCount
);
6919 class ThemeColorTestWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
6921 ThemeColorTestWebFrameClient()
6922 : m_didNotify(false)
6928 m_didNotify
= false;
6931 bool didNotify() const
6937 virtual void didChangeThemeColor()
6945 TEST_P(ParameterizedWebFrameTest
, ThemeColor
)
6947 registerMockedHttpURLLoad("theme_color_test.html");
6948 FrameTestHelpers::WebViewHelper
webViewHelper(this);
6949 ThemeColorTestWebFrameClient client
;
6950 webViewHelper
.initializeAndLoad(m_baseURL
+ "theme_color_test.html", true, &client
);
6951 EXPECT_TRUE(client
.didNotify());
6952 WebLocalFrameImpl
* frame
= webViewHelper
.webViewImpl()->mainFrameImpl();
6953 EXPECT_EQ(0xff0000ff, frame
->document().themeColor());
6954 // Change color by rgb.
6956 frame
->executeScript(WebScriptSource("document.getElementById('tc1').setAttribute('content', 'rgb(0, 0, 0)');"));
6957 EXPECT_TRUE(client
.didNotify());
6958 EXPECT_EQ(0xff000000, frame
->document().themeColor());
6959 // Change color by hsl.
6961 frame
->executeScript(WebScriptSource("document.getElementById('tc1').setAttribute('content', 'hsl(240,100%, 50%)');"));
6962 EXPECT_TRUE(client
.didNotify());
6963 EXPECT_EQ(0xff0000ff, frame
->document().themeColor());
6964 // Change of second theme-color meta tag will not change frame's theme
6967 frame
->executeScript(WebScriptSource("document.getElementById('tc2').setAttribute('content', '#00FF00');"));
6968 EXPECT_TRUE(client
.didNotify());
6969 EXPECT_EQ(0xff0000ff, frame
->document().themeColor());
6972 // Make sure that an embedder-triggered detach with a remote frame parent
6973 // doesn't leave behind dangling pointers.
6974 TEST_P(ParameterizedWebFrameTest
, EmbedderTriggeredDetachWithRemoteMainFrame
)
6976 // FIXME: Refactor some of this logic into WebViewHelper to make it easier to
6977 // write tests with a top-level remote frame.
6978 FrameTestHelpers::TestWebViewClient viewClient
;
6979 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
6980 WebView
* view
= WebView::create(&viewClient
);
6981 view
->setMainFrame(remoteClient
.frame());
6982 FrameTestHelpers::TestWebFrameClient childFrameClient
;
6983 WebLocalFrame
* childFrame
= view
->mainFrame()->toWebRemoteFrame()->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
, nullptr);
6985 // Purposely keep the LocalFrame alive so it's the last thing to be destroyed.
6986 RefPtrWillBePersistent
<Frame
> childCoreFrame
= toCoreFrame(childFrame
);
6988 childCoreFrame
.clear();
6991 class WebFrameSwapTest
: public WebFrameTest
{
6995 registerMockedHttpURLLoad("frame-a-b-c.html");
6996 registerMockedHttpURLLoad("subframe-a.html");
6997 registerMockedHttpURLLoad("subframe-b.html");
6998 registerMockedHttpURLLoad("subframe-c.html");
6999 registerMockedHttpURLLoad("subframe-hello.html");
7001 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "frame-a-b-c.html", true);
7004 void reset() { m_webViewHelper
.reset(); }
7005 WebFrame
* mainFrame() const { return m_webViewHelper
.webView()->mainFrame(); }
7008 FrameTestHelpers::WebViewHelper m_webViewHelper
;
7011 TEST_F(WebFrameSwapTest
, SwapMainFrame
)
7013 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, nullptr);
7014 mainFrame()->swap(remoteFrame
);
7016 FrameTestHelpers::TestWebFrameClient client
;
7017 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7018 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7019 remoteFrame
->swap(localFrame
);
7021 // Finally, make sure an embedder triggered load in the local frame swapped
7023 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7024 std::string content
= localFrame
->contentAsText(1024).utf8();
7025 EXPECT_EQ("hello", content
);
7027 // Manually reset to break WebViewHelper's dependency on the stack allocated
7028 // TestWebFrameClient.
7030 remoteFrame
->close();
7035 class SwapMainFrameWhenTitleChangesWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
7037 SwapMainFrameWhenTitleChangesWebFrameClient() {}
7038 ~SwapMainFrameWhenTitleChangesWebFrameClient() override
{}
7040 void didReceiveTitle(WebLocalFrame
* frame
, const WebString
&, WebTextDirection
) override
7042 if (!frame
->parent())
7043 frame
->swap(WebRemoteFrame::create(WebTreeScopeType::Document
, nullptr));
7047 } // anonymous namespace
7049 TEST_F(WebFrameTest
, SwapMainFrameWhileLoading
)
7051 SwapMainFrameWhenTitleChangesWebFrameClient frameClient
;
7053 FrameTestHelpers::WebViewHelper webViewHelper
;
7054 registerMockedHttpURLLoad("frame-a-b-c.html");
7055 registerMockedHttpURLLoad("subframe-a.html");
7056 registerMockedHttpURLLoad("subframe-b.html");
7057 registerMockedHttpURLLoad("subframe-c.html");
7058 registerMockedHttpURLLoad("subframe-hello.html");
7060 webViewHelper
.initializeAndLoad(m_baseURL
+ "frame-a-b-c.html", true, &frameClient
);
7063 void swapAndVerifyFirstChildConsistency(const char* const message
, WebFrame
* parent
, WebFrame
* newChild
)
7065 SCOPED_TRACE(message
);
7066 parent
->firstChild()->swap(newChild
);
7068 EXPECT_EQ(newChild
, parent
->firstChild());
7069 EXPECT_EQ(newChild
->parent(), parent
);
7070 EXPECT_EQ(newChild
, parent
->lastChild()->previousSibling()->previousSibling());
7071 EXPECT_EQ(newChild
->nextSibling(), parent
->lastChild()->previousSibling());
7074 TEST_F(WebFrameSwapTest
, SwapFirstChild
)
7076 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient
;
7077 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient
);
7078 swapAndVerifyFirstChildConsistency("local->remote", mainFrame(), remoteFrame
);
7080 FrameTestHelpers::TestWebFrameClient client
;
7081 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7082 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7083 swapAndVerifyFirstChildConsistency("remote->local", mainFrame(), localFrame
);
7085 // FIXME: This almost certainly fires more load events on the iframe element
7087 // Finally, make sure an embedder triggered load in the local frame swapped
7089 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7090 std::string content
= localFrame
->contentAsText(1024).utf8();
7091 EXPECT_EQ("hello", content
);
7093 // Manually reset to break WebViewHelper's dependency on the stack allocated
7094 // TestWebFrameClient.
7096 remoteFrame
->close();
7099 void swapAndVerifyMiddleChildConsistency(const char* const message
, WebFrame
* parent
, WebFrame
* newChild
)
7101 SCOPED_TRACE(message
);
7102 parent
->firstChild()->nextSibling()->swap(newChild
);
7104 EXPECT_EQ(newChild
, parent
->firstChild()->nextSibling());
7105 EXPECT_EQ(newChild
, parent
->lastChild()->previousSibling());
7106 EXPECT_EQ(newChild
->parent(), parent
);
7107 EXPECT_EQ(newChild
, parent
->firstChild()->nextSibling());
7108 EXPECT_EQ(newChild
->previousSibling(), parent
->firstChild());
7109 EXPECT_EQ(newChild
, parent
->lastChild()->previousSibling());
7110 EXPECT_EQ(newChild
->nextSibling(), parent
->lastChild());
7113 TEST_F(WebFrameSwapTest
, SwapMiddleChild
)
7115 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient
;
7116 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient
);
7117 swapAndVerifyMiddleChildConsistency("local->remote", mainFrame(), remoteFrame
);
7119 FrameTestHelpers::TestWebFrameClient client
;
7120 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7121 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7122 swapAndVerifyMiddleChildConsistency("remote->local", mainFrame(), localFrame
);
7124 // FIXME: This almost certainly fires more load events on the iframe element
7126 // Finally, make sure an embedder triggered load in the local frame swapped
7128 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7129 std::string content
= localFrame
->contentAsText(1024).utf8();
7130 EXPECT_EQ("hello", content
);
7132 // Manually reset to break WebViewHelper's dependency on the stack allocated
7133 // TestWebFrameClient.
7135 remoteFrame
->close();
7138 void swapAndVerifyLastChildConsistency(const char* const message
, WebFrame
* parent
, WebFrame
* newChild
)
7140 SCOPED_TRACE(message
);
7141 parent
->lastChild()->swap(newChild
);
7143 EXPECT_EQ(newChild
, parent
->lastChild());
7144 EXPECT_EQ(newChild
->parent(), parent
);
7145 EXPECT_EQ(newChild
, parent
->firstChild()->nextSibling()->nextSibling());
7146 EXPECT_EQ(newChild
->previousSibling(), parent
->firstChild()->nextSibling());
7149 TEST_F(WebFrameSwapTest
, SwapLastChild
)
7151 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient
;
7152 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient
);
7153 swapAndVerifyLastChildConsistency("local->remote", mainFrame(), remoteFrame
);
7155 FrameTestHelpers::TestWebFrameClient client
;
7156 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7157 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7158 swapAndVerifyLastChildConsistency("remote->local", mainFrame(), localFrame
);
7160 // FIXME: This almost certainly fires more load events on the iframe element
7162 // Finally, make sure an embedder triggered load in the local frame swapped
7164 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7165 std::string content
= localFrame
->contentAsText(1024).utf8();
7166 EXPECT_EQ("hello", content
);
7168 // Manually reset to break WebViewHelper's dependency on the stack allocated
7169 // TestWebFrameClient.
7171 remoteFrame
->close();
7174 void swapAndVerifySubframeConsistency(const char* const message
, WebFrame
* oldFrame
, WebFrame
* newFrame
)
7176 SCOPED_TRACE(message
);
7178 EXPECT_TRUE(oldFrame
->firstChild());
7179 oldFrame
->swap(newFrame
);
7181 EXPECT_FALSE(newFrame
->firstChild());
7182 EXPECT_FALSE(newFrame
->lastChild());
7185 TEST_F(WebFrameSwapTest
, SwapParentShouldDetachChildren
)
7187 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient1
;
7188 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient1
);
7189 WebFrame
* targetFrame
= mainFrame()->firstChild()->nextSibling();
7190 EXPECT_TRUE(targetFrame
);
7191 swapAndVerifySubframeConsistency("local->remote", targetFrame
, remoteFrame
);
7193 targetFrame
= mainFrame()->firstChild()->nextSibling();
7194 EXPECT_TRUE(targetFrame
);
7196 // Create child frames in the target frame before testing the swap.
7197 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient2
;
7198 WebRemoteFrame
* childRemoteFrame
= remoteFrame
->createRemoteChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &remoteFrameClient2
);
7200 FrameTestHelpers::TestWebFrameClient client
;
7201 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7202 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7203 swapAndVerifySubframeConsistency("remote->local", targetFrame
, localFrame
);
7205 // FIXME: This almost certainly fires more load events on the iframe element
7207 // Finally, make sure an embedder triggered load in the local frame swapped
7209 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7210 std::string content
= localFrame
->contentAsText(1024).utf8();
7211 EXPECT_EQ("hello", content
);
7213 // Manually reset to break WebViewHelper's dependency on the stack allocated
7214 // TestWebFrameClient.
7216 remoteFrame
->close();
7217 childRemoteFrame
->close();
7220 TEST_F(WebFrameSwapTest
, SwapPreservesGlobalContext
)
7222 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7223 v8::Local
<v8::Value
> windowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window"));
7224 ASSERT_TRUE(windowTop
->IsObject());
7225 v8::Local
<v8::Value
> originalWindow
= mainFrame()->executeScriptAndReturnValue(WebScriptSource(
7226 "document.querySelector('#frame2').contentWindow;"));
7227 ASSERT_TRUE(originalWindow
->IsObject());
7229 // Make sure window reference stays the same when swapping to a remote frame.
7230 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7231 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7232 WebFrame
* targetFrame
= mainFrame()->firstChild()->nextSibling();
7233 targetFrame
->swap(remoteFrame
);
7234 remoteFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7235 v8::Local
<v8::Value
> remoteWindow
= mainFrame()->executeScriptAndReturnValue(WebScriptSource(
7236 "document.querySelector('#frame2').contentWindow;"));
7237 EXPECT_TRUE(originalWindow
->StrictEquals(remoteWindow
));
7238 // Check that its view is consistent with the world.
7239 v8::Local
<v8::Value
> remoteWindowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource(
7240 "document.querySelector('#frame2').contentWindow.top;"));
7241 EXPECT_TRUE(windowTop
->StrictEquals(remoteWindowTop
));
7243 // Now check that remote -> local works too, since it goes through a different code path.
7244 FrameTestHelpers::TestWebFrameClient client
;
7245 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7246 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7247 remoteFrame
->swap(localFrame
);
7248 v8::Local
<v8::Value
> localWindow
= mainFrame()->executeScriptAndReturnValue(WebScriptSource(
7249 "document.querySelector('#frame2').contentWindow;"));
7250 EXPECT_TRUE(originalWindow
->StrictEquals(localWindow
));
7251 v8::Local
<v8::Value
> localWindowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource(
7252 "document.querySelector('#frame2').contentWindow.top;"));
7253 EXPECT_TRUE(windowTop
->StrictEquals(localWindowTop
));
7255 // Manually reset to break WebViewHelper's dependency on the stack allocated
7256 // TestWebFrameClient.
7260 TEST_F(WebFrameSwapTest
, SwapInitializesGlobal
)
7262 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7264 v8::Local
<v8::Value
> windowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window"));
7265 ASSERT_TRUE(windowTop
->IsObject());
7267 v8::Local
<v8::Value
> lastChild
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved = window[2]"));
7268 ASSERT_TRUE(lastChild
->IsObject());
7270 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7271 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7272 mainFrame()->lastChild()->swap(remoteFrame
);
7273 remoteFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7274 v8::Local
<v8::Value
> remoteWindowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved.top"));
7275 EXPECT_TRUE(remoteWindowTop
->IsObject());
7276 EXPECT_TRUE(windowTop
->StrictEquals(remoteWindowTop
));
7278 FrameTestHelpers::TestWebFrameClient client
;
7279 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7280 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7281 remoteFrame
->swap(localFrame
);
7282 v8::Local
<v8::Value
> localWindowTop
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved.top"));
7283 EXPECT_TRUE(localWindowTop
->IsObject());
7284 EXPECT_TRUE(windowTop
->StrictEquals(localWindowTop
));
7289 TEST_F(WebFrameSwapTest
, RemoteFramesAreIndexable
)
7291 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7293 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7294 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7295 mainFrame()->lastChild()->swap(remoteFrame
);
7296 remoteFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7297 v8::Local
<v8::Value
> remoteWindow
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window[2]"));
7298 EXPECT_TRUE(remoteWindow
->IsObject());
7299 v8::Local
<v8::Value
> windowLength
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window.length"));
7300 ASSERT_TRUE(windowLength
->IsInt32());
7301 EXPECT_EQ(3, windowLength
.As
<v8::Int32
>()->Value());
7306 TEST_F(WebFrameSwapTest
, RemoteFrameLengthAccess
)
7308 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7310 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7311 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7312 mainFrame()->lastChild()->swap(remoteFrame
);
7313 remoteFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7314 v8::Local
<v8::Value
> remoteWindowLength
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window[2].length"));
7315 ASSERT_TRUE(remoteWindowLength
->IsInt32());
7316 EXPECT_EQ(0, remoteWindowLength
.As
<v8::Int32
>()->Value());
7321 TEST_F(WebFrameSwapTest
, RemoteWindowNamedAccess
)
7323 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7325 // FIXME: Once OOPIF unit test infrastructure is in place, test that named
7326 // window access on a remote window works. For now, just test that accessing
7327 // a named property doesn't crash.
7328 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7329 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7330 mainFrame()->lastChild()->swap(remoteFrame
);
7331 remoteFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7332 v8::Local
<v8::Value
> remoteWindowProperty
= mainFrame()->executeScriptAndReturnValue(WebScriptSource("window[2].foo"));
7333 EXPECT_TRUE(remoteWindowProperty
.IsEmpty());
7338 // TODO(alexmos, dcheng): This test and some other OOPIF tests use
7339 // very little of the test fixture support in WebFrameSwapTest. We should
7340 // clean these tests up.
7341 TEST_F(WebFrameSwapTest
, FramesOfRemoteParentAreIndexable
)
7343 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7345 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7346 WebRemoteFrame
* remoteParentFrame
= remoteClient
.frame();
7347 mainFrame()->swap(remoteParentFrame
);
7348 remoteParentFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7350 FrameTestHelpers::TestWebFrameClient childFrameClient
;
7351 WebLocalFrame
* childFrame
= remoteParentFrame
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
, nullptr);
7352 FrameTestHelpers::loadFrame(childFrame
, m_baseURL
+ "subframe-hello.html");
7354 v8::Local
<v8::Value
> window
= childFrame
->executeScriptAndReturnValue(WebScriptSource("window"));
7355 v8::Local
<v8::Value
> childOfRemoteParent
= childFrame
->executeScriptAndReturnValue(WebScriptSource("parent.frames[0]"));
7356 EXPECT_TRUE(childOfRemoteParent
->IsObject());
7357 EXPECT_TRUE(window
->StrictEquals(childOfRemoteParent
));
7359 v8::Local
<v8::Value
> windowLength
= childFrame
->executeScriptAndReturnValue(WebScriptSource("parent.frames.length"));
7360 ASSERT_TRUE(windowLength
->IsInt32());
7361 EXPECT_EQ(1, windowLength
.As
<v8::Int32
>()->Value());
7363 // Manually reset to break WebViewHelper's dependency on the stack allocated clients.
7367 // Check that frames with a remote parent don't crash while accessing window.frameElement.
7368 TEST_F(WebFrameSwapTest
, FrameElementInFramesWithRemoteParent
)
7370 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7372 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7373 WebRemoteFrame
* remoteParentFrame
= remoteClient
.frame();
7374 mainFrame()->swap(remoteParentFrame
);
7375 remoteParentFrame
->setReplicatedOrigin(SecurityOrigin::createUnique());
7377 FrameTestHelpers::TestWebFrameClient childFrameClient
;
7378 WebLocalFrame
* childFrame
= remoteParentFrame
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
, nullptr);
7379 FrameTestHelpers::loadFrame(childFrame
, m_baseURL
+ "subframe-hello.html");
7381 v8::Local
<v8::Value
> frameElement
= childFrame
->executeScriptAndReturnValue(WebScriptSource("window.frameElement"));
7382 // frameElement shouldn't be accessible cross-origin.
7383 EXPECT_TRUE(frameElement
.IsEmpty());
7385 // Manually reset to break WebViewHelper's dependency on the stack allocated clients.
7389 class RemoteToLocalSwapWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
7391 explicit RemoteToLocalSwapWebFrameClient(WebRemoteFrame
* remoteFrame
)
7392 : m_historyCommitType(WebHistoryInertCommit
)
7393 , m_remoteFrame(remoteFrame
)
7397 void didCommitProvisionalLoad(WebLocalFrame
* frame
, const WebHistoryItem
&, WebHistoryCommitType historyCommitType
) override
7399 m_historyCommitType
= historyCommitType
;
7400 m_remoteFrame
->swap(frame
);
7403 WebHistoryCommitType
historyCommitType() const { return m_historyCommitType
; }
7405 WebHistoryCommitType m_historyCommitType
;
7406 WebRemoteFrame
* m_remoteFrame
;
7409 // The commit type should be Initial if we are swapping a RemoteFrame to a
7410 // LocalFrame as it is first being created. This happens when another frame
7411 // exists in the same process, such that we create the RemoteFrame before the
7412 // first navigation occurs.
7413 TEST_F(WebFrameSwapTest
, HistoryCommitTypeAfterNewRemoteToLocalSwap
)
7415 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient
;
7416 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient
);
7417 WebFrame
* targetFrame
= mainFrame()->firstChild();
7418 ASSERT_TRUE(targetFrame
);
7419 targetFrame
->swap(remoteFrame
);
7420 ASSERT_TRUE(mainFrame()->firstChild());
7421 ASSERT_EQ(mainFrame()->firstChild(), remoteFrame
);
7423 RemoteToLocalSwapWebFrameClient
client(remoteFrame
);
7424 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7425 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7426 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7427 EXPECT_EQ(WebInitialCommitInChildFrame
, client
.historyCommitType());
7429 // Manually reset to break WebViewHelper's dependency on the stack allocated
7430 // TestWebFrameClient.
7432 remoteFrame
->close();
7435 // The commit type should be Standard if we are swapping a RemoteFrame to a
7436 // LocalFrame after commits have already happened in the frame. The browser
7437 // process will inform us via setCommittedFirstRealLoad.
7438 TEST_F(WebFrameSwapTest
, HistoryCommitTypeAfterExistingRemoteToLocalSwap
)
7440 FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient
;
7441 WebRemoteFrame
* remoteFrame
= WebRemoteFrame::create(WebTreeScopeType::Document
, &remoteFrameClient
);
7442 WebFrame
* targetFrame
= mainFrame()->firstChild();
7443 ASSERT_TRUE(targetFrame
);
7444 targetFrame
->swap(remoteFrame
);
7445 ASSERT_TRUE(mainFrame()->firstChild());
7446 ASSERT_EQ(mainFrame()->firstChild(), remoteFrame
);
7448 RemoteToLocalSwapWebFrameClient
client(remoteFrame
);
7449 WebLocalFrame
* localFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &client
);
7450 localFrame
->initializeToReplaceRemoteFrame(remoteFrame
, "", WebSandboxFlags::None
);
7451 localFrame
->setCommittedFirstRealLoad();
7452 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "subframe-hello.html");
7453 EXPECT_EQ(WebStandardCommit
, client
.historyCommitType());
7455 // Manually reset to break WebViewHelper's dependency on the stack allocated
7456 // TestWebFrameClient.
7458 remoteFrame
->close();
7461 class RemoteNavigationClient
: public FrameTestHelpers::TestWebRemoteFrameClient
{
7463 void navigate(const WebURLRequest
& request
, bool shouldReplaceCurrentEntry
) override
7465 m_lastRequest
= request
;
7468 const WebURLRequest
& lastRequest() const { return m_lastRequest
; }
7471 WebURLRequest m_lastRequest
;
7474 TEST_F(WebFrameSwapTest
, NavigateRemoteFrameViaLocation
)
7476 RemoteNavigationClient client
;
7477 WebRemoteFrame
* remoteFrame
= client
.frame();
7478 WebFrame
* targetFrame
= mainFrame()->firstChild();
7479 ASSERT_TRUE(targetFrame
);
7480 targetFrame
->swap(remoteFrame
);
7481 ASSERT_TRUE(mainFrame()->firstChild());
7482 ASSERT_EQ(mainFrame()->firstChild(), remoteFrame
);
7484 remoteFrame
->setReplicatedOrigin(WebSecurityOrigin::createFromString("http://127.0.0.1"));
7485 mainFrame()->executeScript(WebScriptSource(
7486 "document.getElementsByTagName('iframe')[0].contentWindow.location = 'data:text/html,hi'"));
7487 ASSERT_FALSE(client
.lastRequest().isNull());
7488 EXPECT_EQ(WebURL(toKURL("data:text/html,hi")), client
.lastRequest().url());
7490 // Manually reset to break WebViewHelper's dependency on the stack allocated
7491 // TestWebFrameClient.
7495 TEST_F(WebFrameSwapTest
, WindowOpenOnRemoteFrame
)
7497 RemoteNavigationClient remoteClient
;
7498 WebRemoteFrame
* remoteFrame
= remoteClient
.frame();
7499 mainFrame()->firstChild()->swap(remoteFrame
);
7500 remoteFrame
->setReplicatedOrigin(WebSecurityOrigin::createFromString("http://127.0.0.1"));
7502 ASSERT_TRUE(mainFrame()->isWebLocalFrame());
7503 ASSERT_TRUE(mainFrame()->firstChild()->isWebRemoteFrame());
7504 LocalDOMWindow
* mainWindow
= toWebLocalFrameImpl(mainFrame())->frame()->localDOMWindow();
7506 KURL destination
= toKURL("data:text/html:destination");
7507 mainWindow
->open(destination
.string(), "frame1", "", mainWindow
, mainWindow
);
7508 ASSERT_FALSE(remoteClient
.lastRequest().isNull());
7509 EXPECT_EQ(remoteClient
.lastRequest().url(), WebURL(destination
));
7511 // Pointing a named frame to an empty URL should just return a reference to
7512 // the frame's window without navigating it.
7513 RefPtrWillBeRawPtr
<DOMWindow
> result
= mainWindow
->open("", "frame1", "", mainWindow
, mainWindow
);
7514 EXPECT_EQ(remoteClient
.lastRequest().url(), WebURL(destination
));
7515 EXPECT_EQ(result
, toCoreFrame(remoteFrame
)->domWindow());
7520 class RemoteWindowCloseClient
: public FrameTestHelpers::TestWebViewClient
{
7522 RemoteWindowCloseClient()
7527 void closeWidgetSoon() override
7532 bool closed() const { return m_closed
; }
7538 TEST_F(WebFrameTest
, WindowOpenRemoteClose
)
7540 FrameTestHelpers::WebViewHelper mainWebView
;
7541 mainWebView
.initialize(true);
7543 // Create a remote window that will be closed later in the test.
7544 RemoteWindowCloseClient viewClient
;
7545 FrameTestHelpers::TestWebRemoteFrameClient frameClient
;
7546 WebRemoteFrame
* webRemoteFrame
= frameClient
.frame();
7548 WebView
* view
= WebView::create(&viewClient
);
7549 view
->setMainFrame(webRemoteFrame
);
7550 view
->mainFrame()->setOpener(mainWebView
.webView()->mainFrame());
7551 webRemoteFrame
->setReplicatedOrigin(WebSecurityOrigin::createFromString("http://127.0.0.1"));
7553 LocalFrame
* localFrame
= toLocalFrame(toCoreFrame(mainWebView
.webView()->mainFrame()));
7554 RemoteFrame
* remoteFrame
= toRemoteFrame(toCoreFrame(frameClient
.frame()));
7556 // Attempt to close the window, which should fail as it isn't opened
7558 remoteFrame
->domWindow()->close(localFrame
->document());
7559 EXPECT_FALSE(viewClient
.closed());
7561 // Marking it as opened by a script should now allow it to be closed.
7562 remoteFrame
->page()->setOpenedByDOM();
7563 remoteFrame
->domWindow()->close(localFrame
->document());
7564 EXPECT_TRUE(viewClient
.closed());
7569 TEST_F(WebFrameTest
, NavigateRemoteToLocalWithOpener
)
7571 FrameTestHelpers::WebViewHelper mainWebView
;
7572 mainWebView
.initialize(true);
7573 WebFrame
* mainFrame
= mainWebView
.webView()->mainFrame();
7575 // Create a popup with a remote frame and set its opener to the main frame.
7576 FrameTestHelpers::TestWebViewClient popupViewClient
;
7577 WebView
* popupView
= WebView::create(&popupViewClient
);
7578 FrameTestHelpers::TestWebRemoteFrameClient popupRemoteClient
;
7579 WebRemoteFrame
* popupRemoteFrame
= popupRemoteClient
.frame();
7580 popupView
->setMainFrame(popupRemoteFrame
);
7581 popupRemoteFrame
->setOpener(mainFrame
);
7582 popupRemoteFrame
->setReplicatedOrigin(WebSecurityOrigin::createFromString("http://foo.com"));
7583 EXPECT_FALSE(mainFrame
->securityOrigin().canAccess(popupView
->mainFrame()->securityOrigin()));
7585 // Do a remote-to-local swap in the popup.
7586 FrameTestHelpers::TestWebFrameClient popupLocalClient
;
7587 WebLocalFrame
* popupLocalFrame
= WebLocalFrame::create(WebTreeScopeType::Document
, &popupLocalClient
);
7588 popupLocalFrame
->initializeToReplaceRemoteFrame(popupRemoteFrame
, "", WebSandboxFlags::None
);
7589 popupRemoteFrame
->swap(popupLocalFrame
);
7591 // The initial document created during the remote-to-local swap should have
7592 // inherited its opener's SecurityOrigin.
7593 EXPECT_TRUE(mainFrame
->securityOrigin().canAccess(popupView
->mainFrame()->securityOrigin()));
7598 class CommitTypeWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
7600 explicit CommitTypeWebFrameClient()
7601 : m_historyCommitType(WebHistoryInertCommit
)
7605 void didCommitProvisionalLoad(WebLocalFrame
*, const WebHistoryItem
&, WebHistoryCommitType historyCommitType
) override
7607 m_historyCommitType
= historyCommitType
;
7610 WebHistoryCommitType
historyCommitType() const { return m_historyCommitType
; }
7613 WebHistoryCommitType m_historyCommitType
;
7616 TEST_P(ParameterizedWebFrameTest
, RemoteFrameInitialCommitType
)
7618 FrameTestHelpers::TestWebViewClient viewClient
;
7619 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7620 WebView
* view
= WebView::create(&viewClient
);
7621 view
->setMainFrame(remoteClient
.frame());
7622 toRemoteFrame(toCoreFrame(view
->mainFrame()))->securityContext()->setReplicatedOrigin(SecurityOrigin::create(toKURL(m_baseURL
)));
7624 // If an iframe has a remote main frame, ensure the inital commit is correctly identified as WebInitialCommitInChildFrame.
7625 CommitTypeWebFrameClient childFrameClient
;
7626 WebLocalFrame
* childFrame
= view
->mainFrame()->toWebRemoteFrame()->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
, nullptr);
7627 registerMockedHttpURLLoad("foo.html");
7628 FrameTestHelpers::loadFrame(childFrame
, m_baseURL
+ "foo.html");
7629 EXPECT_EQ(WebInitialCommitInChildFrame
, childFrameClient
.historyCommitType());
7633 class GestureEventTestWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
7635 GestureEventTestWebViewClient() : m_didHandleGestureEvent(false) { }
7636 void didHandleGestureEvent(const WebGestureEvent
& event
, bool eventCancelled
) override
{ m_didHandleGestureEvent
= true; }
7637 bool didHandleGestureEvent() const { return m_didHandleGestureEvent
; }
7640 bool m_didHandleGestureEvent
;
7643 TEST_P(ParameterizedWebFrameTest
, FrameWidgetTest
)
7645 FrameTestHelpers::TestWebViewClient viewClient
;
7646 WebView
* view
= WebView::create(&viewClient
);
7648 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7649 view
->setMainFrame(remoteClient
.frame());
7651 FrameTestHelpers::TestWebFrameClient childFrameClient
;
7652 WebLocalFrame
* childFrame
= view
->mainFrame()->toWebRemoteFrame()->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
, nullptr);
7654 GestureEventTestWebViewClient childViewClient
;
7655 WebFrameWidget
* widget
= WebFrameWidget::create(&childViewClient
, childFrame
);
7657 view
->resize(WebSize(1000, 1000));
7660 widget
->handleInputEvent(fatTap(20, 20));
7661 EXPECT_TRUE(childViewClient
.didHandleGestureEvent());
7667 class MockDocumentThreadableLoaderClient
: public DocumentThreadableLoaderClient
{
7669 MockDocumentThreadableLoaderClient() : m_failed(false) { }
7670 void didFail(const ResourceError
&) override
{ m_failed
= true;}
7672 void reset() { m_failed
= false; }
7673 bool failed() { return m_failed
; }
7678 // FIXME: This would be better as a unittest on DocumentThreadableLoader but it
7679 // requires spin-up of a frame. It may be possible to remove that requirement
7680 // and convert it to a unittest.
7681 TEST_P(ParameterizedWebFrameTest
, LoaderOriginAccess
)
7683 FrameTestHelpers::WebViewHelper
webViewHelper(this);
7684 webViewHelper
.initializeAndLoad("about:blank");
7686 SchemeRegistry::registerURLSchemeAsDisplayIsolated("chrome");
7688 // Cross-origin request.
7689 KURL
resourceUrl(ParsedURLString
, "chrome://test.pdf");
7690 registerMockedChromeURLLoad("test.pdf");
7692 RefPtrWillBeRawPtr
<LocalFrame
> frame(toLocalFrame(webViewHelper
.webViewImpl()->page()->mainFrame()));
7694 MockDocumentThreadableLoaderClient client
;
7695 ThreadableLoaderOptions options
;
7697 // First try to load the request with regular access. Should fail.
7698 options
.crossOriginRequestPolicy
= UseAccessControl
;
7699 ResourceLoaderOptions resourceLoaderOptions
;
7700 DocumentThreadableLoader::loadResourceSynchronously(
7701 *frame
->document(), ResourceRequest(resourceUrl
), client
, options
, resourceLoaderOptions
);
7702 EXPECT_TRUE(client
.failed());
7705 // Try to load the request with cross origin access. Should succeed.
7706 options
.crossOriginRequestPolicy
= AllowCrossOriginRequests
;
7707 DocumentThreadableLoader::loadResourceSynchronously(
7708 *frame
->document(), ResourceRequest(resourceUrl
), client
, options
, resourceLoaderOptions
);
7709 EXPECT_FALSE(client
.failed());
7712 TEST_P(ParameterizedWebFrameTest
, DetachRemoteFrame
)
7714 FrameTestHelpers::TestWebViewClient viewClient
;
7715 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7716 WebView
* view
= WebView::create(&viewClient
);
7717 view
->setMainFrame(remoteClient
.frame());
7718 FrameTestHelpers::TestWebRemoteFrameClient childFrameClient
;
7719 WebRemoteFrame
* childFrame
= view
->mainFrame()->toWebRemoteFrame()->createRemoteChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &childFrameClient
);
7720 childFrame
->detach();
7722 childFrame
->close();
7725 class TestConsoleMessageWebFrameClient
: public FrameTestHelpers::TestWebFrameClient
{
7727 virtual void didAddMessageToConsole(const WebConsoleMessage
& message
, const WebString
& sourceName
, unsigned sourceLine
, const WebString
& stackTrace
)
7729 messages
.push_back(message
);
7732 std::vector
<WebConsoleMessage
> messages
;
7735 TEST_P(ParameterizedWebFrameTest
, CrossDomainAccessErrorsUseCallingWindow
)
7737 registerMockedHttpURLLoad("hidden_frames.html");
7738 registerMockedChromeURLLoad("hello_world.html");
7740 FrameTestHelpers::WebViewHelper
webViewHelper(this);
7741 TestConsoleMessageWebFrameClient webFrameClient
;
7742 FrameTestHelpers::TestWebViewClient webViewClient
;
7743 webViewHelper
.initializeAndLoad(m_baseURL
+ "hidden_frames.html", true, &webFrameClient
, &webViewClient
);
7745 // Create another window with a cross-origin page, and point its opener to
7747 FrameTestHelpers::WebViewHelper
popupWebViewHelper(this);
7748 TestConsoleMessageWebFrameClient popupWebFrameClient
;
7749 WebView
* popupView
= popupWebViewHelper
.initializeAndLoad(m_chromeURL
+ "hello_world.html", true, &popupWebFrameClient
);
7750 popupView
->mainFrame()->setOpener(webViewHelper
.webView()->mainFrame());
7752 // Attempt a blocked navigation of an opener's subframe, and ensure that
7753 // the error shows up on the popup (calling) window's console, rather than
7754 // the target window.
7755 popupView
->mainFrame()->executeScript(WebScriptSource("opener.frames[1].location.href='data:text/html,foo'"));
7756 EXPECT_TRUE(webFrameClient
.messages
.empty());
7757 ASSERT_EQ(1u, popupWebFrameClient
.messages
.size());
7758 EXPECT_TRUE(std::string::npos
!= popupWebFrameClient
.messages
[0].text
.utf8().find("Unsafe JavaScript attempt to initiate navigation"));
7760 // Try setting a cross-origin iframe element's source to a javascript: URL,
7761 // and check that this error is also printed on the calling window.
7762 popupView
->mainFrame()->executeScript(WebScriptSource("opener.document.querySelectorAll('iframe')[1].src='javascript:alert()'"));
7763 EXPECT_TRUE(webFrameClient
.messages
.empty());
7764 ASSERT_EQ(2u, popupWebFrameClient
.messages
.size());
7765 EXPECT_TRUE(std::string::npos
!= popupWebFrameClient
.messages
[1].text
.utf8().find("Blocked a frame"));
7767 // Manually reset to break WebViewHelpers' dependencies on the stack
7768 // allocated WebFrameClients.
7769 webViewHelper
.reset();
7770 popupWebViewHelper
.reset();
7773 class DeviceEmulationTest
: public ParameterizedWebFrameTest
{
7775 DeviceEmulationTest()
7776 : m_webViewHelper(this)
7778 registerMockedHttpURLLoad("device_emulation.html");
7779 m_client
.m_screenInfo
.deviceScaleFactor
= 1;
7780 m_webViewHelper
.initializeAndLoad(m_baseURL
+ "device_emulation.html", true, 0, &m_client
);
7783 void testResize(const WebSize size
, const String
& expectedSize
)
7785 m_client
.m_screenInfo
.rect
= WebRect(0, 0, size
.width
, size
.height
);
7786 m_client
.m_screenInfo
.availableRect
= m_client
.m_screenInfo
.rect
;
7787 m_webViewHelper
.webView()->resize(size
);
7788 m_webViewHelper
.webView()->layout();
7789 EXPECT_EQ(expectedSize
, dumpSize("test"));
7792 String
dumpSize(const String
& id
)
7794 String code
= "dumpSize('" + id
+ "')";
7795 v8::HandleScope
scope(v8::Isolate::GetCurrent());
7796 ScriptExecutionCallbackHelper
callbackHelper(m_webViewHelper
.webView()->mainFrame()->mainWorldScriptContext());
7797 m_webViewHelper
.webView()->mainFrame()->toWebLocalFrame()->requestExecuteScriptAndReturnValue(WebScriptSource(WebString(code
)), false, &callbackHelper
);
7799 EXPECT_TRUE(callbackHelper
.didComplete());
7800 return callbackHelper
.stringValue();
7803 FixedLayoutTestWebViewClient m_client
;
7804 FrameTestHelpers::WebViewHelper m_webViewHelper
;
7807 INSTANTIATE_TEST_CASE_P(All
, DeviceEmulationTest
, ::testing::Values(
7808 ParameterizedWebFrameTestConfig::Default
,
7809 ParameterizedWebFrameTestConfig::RootLayerScrolls
));
7811 TEST_P(DeviceEmulationTest
, DeviceSizeInvalidatedOnResize
)
7813 WebDeviceEmulationParams params
;
7814 params
.screenPosition
= WebDeviceEmulationParams::Mobile
;
7815 m_webViewHelper
.webView()->enableDeviceEmulation(params
);
7817 testResize(WebSize(700, 500), "300x300");
7818 testResize(WebSize(710, 500), "400x300");
7819 testResize(WebSize(690, 500), "200x300");
7820 testResize(WebSize(700, 510), "300x400");
7821 testResize(WebSize(700, 490), "300x200");
7822 testResize(WebSize(710, 510), "400x400");
7823 testResize(WebSize(690, 490), "200x200");
7824 testResize(WebSize(800, 600), "400x400");
7826 m_webViewHelper
.webView()->disableDeviceEmulation();
7829 TEST_P(DeviceEmulationTest
, PointerAndHoverTypes
)
7831 WebDeviceEmulationParams params
;
7832 params
.screenPosition
= WebDeviceEmulationParams::Mobile
;
7833 m_webViewHelper
.webView()->enableDeviceEmulation(params
);
7834 EXPECT_EQ("20x20", dumpSize("pointer"));
7835 m_webViewHelper
.webView()->disableDeviceEmulation();
7838 class WebLocalFrameScope final
{
7840 WebLocalFrameScope(WebLocalFrame
* localFrame
)
7841 : m_localFrame(localFrame
)
7845 operator WebLocalFrame
*() const
7847 return m_localFrame
;
7850 WebLocalFrame
* operator->() const
7852 return m_localFrame
;
7855 ~WebLocalFrameScope()
7857 m_localFrame
->close();
7860 WebLocalFrame
* m_localFrame
;
7864 TEST_P(ParameterizedWebFrameTest
, CreateLocalChildWithPreviousSibling
)
7866 FrameTestHelpers::TestWebViewClient viewClient
;
7867 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7868 WebView
* view
= WebView::create(&viewClient
);
7869 view
->setMainFrame(remoteClient
.frame());
7870 WebRemoteFrame
* parent
= view
->mainFrame()->toWebRemoteFrame();
7872 WebLocalFrameScope secondFrame
= parent
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, nullptr, nullptr);
7873 WebLocalFrameScope fourthFrame
= parent
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, nullptr, secondFrame
);
7874 WebLocalFrameScope thirdFrame
= parent
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, nullptr, secondFrame
);
7875 WebLocalFrameScope firstFrame
= parent
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, nullptr, nullptr);
7877 EXPECT_EQ(firstFrame
, parent
->firstChild());
7878 EXPECT_EQ(nullptr, firstFrame
->previousSibling());
7879 EXPECT_EQ(secondFrame
, firstFrame
->nextSibling());
7881 EXPECT_EQ(firstFrame
, secondFrame
->previousSibling());
7882 EXPECT_EQ(thirdFrame
, secondFrame
->nextSibling());
7884 EXPECT_EQ(secondFrame
, thirdFrame
->previousSibling());
7885 EXPECT_EQ(fourthFrame
, thirdFrame
->nextSibling());
7887 EXPECT_EQ(thirdFrame
, fourthFrame
->previousSibling());
7888 EXPECT_EQ(nullptr, fourthFrame
->nextSibling());
7889 EXPECT_EQ(fourthFrame
, parent
->lastChild());
7891 EXPECT_EQ(parent
, firstFrame
->parent());
7892 EXPECT_EQ(parent
, secondFrame
->parent());
7893 EXPECT_EQ(parent
, thirdFrame
->parent());
7894 EXPECT_EQ(parent
, fourthFrame
->parent());
7899 TEST_P(ParameterizedWebFrameTest
, SendBeaconFromChildWithRemoteMainFrame
)
7901 FrameTestHelpers::TestWebViewClient viewClient
;
7902 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7903 WebView
* view
= WebView::create(&viewClient
);
7904 view
->settings()->setJavaScriptEnabled(true);
7905 view
->setMainFrame(remoteClient
.frame());
7906 WebRemoteFrame
* root
= view
->mainFrame()->toWebRemoteFrame();
7907 root
->setReplicatedOrigin(SecurityOrigin::createUnique());
7909 FrameTestHelpers::TestWebFrameClient localFrameClient
;
7910 WebLocalFrame
* localFrame
= root
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &localFrameClient
, nullptr);
7912 // Finally, make sure an embedder triggered load in the local frame swapped
7914 registerMockedHttpURLLoad("send_beacon.html");
7915 registerMockedHttpURLLoad("reload_post.html"); // url param to sendBeacon()
7916 FrameTestHelpers::loadFrame(localFrame
, m_baseURL
+ "send_beacon.html");
7921 // See https://crbug.com/525285.
7922 TEST_P(ParameterizedWebFrameTest
, RemoteToLocalSwapOnMainFrameInitializesCoreFrame
)
7924 FrameTestHelpers::TestWebViewClient viewClient
;
7925 FrameTestHelpers::TestWebRemoteFrameClient remoteClient
;
7926 WebView
* view
= WebView::create(&viewClient
);
7927 view
->setMainFrame(remoteClient
.frame());
7928 WebRemoteFrame
* remoteRoot
= view
->mainFrame()->toWebRemoteFrame();
7929 remoteRoot
->setReplicatedOrigin(SecurityOrigin::createUnique());
7931 FrameTestHelpers::TestWebFrameClient localFrameClient
;
7932 remoteRoot
->createLocalChild(WebTreeScopeType::Document
, "", WebSandboxFlags::None
, &localFrameClient
, nullptr);
7934 // Do a remote-to-local swap of the top frame.
7935 FrameTestHelpers::TestWebFrameClient localClient
;
7936 WebLocalFrame
* localRoot
= WebLocalFrame::create(WebTreeScopeType::Document
, &localClient
);
7937 localRoot
->initializeToReplaceRemoteFrame(remoteRoot
, "", WebSandboxFlags::None
);
7938 remoteRoot
->swap(localRoot
);
7940 // Load a page with a child frame in the new root to make sure this doesn't
7941 // crash when the child frame invokes setCoreFrame.
7942 registerMockedHttpURLLoad("single_iframe.html");
7943 registerMockedHttpURLLoad("visible_iframe.html");
7944 FrameTestHelpers::loadFrame(localRoot
, m_baseURL
+ "single_iframe.html");
7949 class OverscrollWebViewClient
: public FrameTestHelpers::TestWebViewClient
{
7951 MOCK_METHOD4(didOverscroll
, void(const WebFloatSize
&, const WebFloatSize
&, const WebFloatPoint
&, const WebFloatSize
&));
7954 class WebFrameOverscrollTest
: public WebFrameTest
{
7956 WebGestureEvent
generateEvent(WebInputEvent::Type type
, float deltaX
= 0.0, float deltaY
= 0.0)
7958 WebGestureEvent event
;
7962 if (type
== WebInputEvent::GestureScrollUpdate
) {
7963 event
.data
.scrollUpdate
.deltaX
= deltaX
;
7964 event
.data
.scrollUpdate
.deltaY
= deltaY
;
7969 void ScrollByWheel(FrameTestHelpers::WebViewHelper
* webViewHelper
, int windowX
, int windowY
, float deltaX
, float deltaY
)
7971 WebMouseWheelEvent event
;
7972 event
.type
= WebInputEvent::MouseWheel
;
7973 event
.deltaX
= deltaX
;
7974 event
.deltaY
= deltaY
;
7975 event
.windowX
= windowX
;
7976 event
.windowY
= windowY
;
7977 event
.canScroll
= true;
7978 webViewHelper
->webViewImpl()->handleInputEvent(event
);
7981 void ScrollBegin(FrameTestHelpers::WebViewHelper
* webViewHelper
)
7983 webViewHelper
->webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin
));
7986 void ScrollUpdate(FrameTestHelpers::WebViewHelper
* webViewHelper
, float deltaX
, float deltaY
)
7988 webViewHelper
->webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate
, deltaX
, deltaY
));
7991 void ScrollEnd(FrameTestHelpers::WebViewHelper
* webViewHelper
)
7993 webViewHelper
->webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd
));
7997 TEST_F(WebFrameOverscrollTest
, AccumulatedRootOverscrollAndUnsedDeltaValuesOnOverscroll
)
7999 OverscrollWebViewClient client
;
8000 registerMockedHttpURLLoad("overscroll/overscroll.html");
8001 FrameTestHelpers::WebViewHelper webViewHelper
;
8002 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/overscroll.html", true, 0, &client
, configureAndroid
);
8004 // Calculation of accumulatedRootOverscroll and unusedDelta on multiple scrollUpdate.
8005 ScrollBegin(&webViewHelper
);
8006 EXPECT_CALL(client
, didOverscroll(WebFloatSize(8, 16), WebFloatSize(8, 16), WebFloatPoint(100, 100), WebFloatSize()));
8007 ScrollUpdate(&webViewHelper
, -308, -316);
8008 Mock::VerifyAndClearExpectations(&client
);
8010 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, 13), WebFloatSize(8, 29), WebFloatPoint(100, 100), WebFloatSize()));
8011 ScrollUpdate(&webViewHelper
, 0, -13);
8012 Mock::VerifyAndClearExpectations(&client
);
8014 EXPECT_CALL(client
, didOverscroll(WebFloatSize(20, 13), WebFloatSize(28, 42), WebFloatPoint(100, 100), WebFloatSize()));
8015 ScrollUpdate(&webViewHelper
, -20, -13);
8016 Mock::VerifyAndClearExpectations(&client
);
8018 // Overscroll is not reported.
8019 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8020 ScrollUpdate(&webViewHelper
, 0, 1);
8021 Mock::VerifyAndClearExpectations(&client
);
8023 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8024 ScrollUpdate(&webViewHelper
, 1, 0);
8025 Mock::VerifyAndClearExpectations(&client
);
8027 // Overscroll is reported.
8028 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, -701), WebFloatSize(0, -701), WebFloatPoint(100, 100), WebFloatSize()));
8029 ScrollUpdate(&webViewHelper
, 0, 1000);
8030 Mock::VerifyAndClearExpectations(&client
);
8032 // Overscroll is not reported.
8033 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8034 ScrollEnd(&webViewHelper
);
8035 Mock::VerifyAndClearExpectations(&client
);
8038 TEST_F(WebFrameOverscrollTest
, AccumulatedOverscrollAndUnusedDeltaValuesOnDifferentAxesOverscroll
)
8040 OverscrollWebViewClient client
;
8041 registerMockedHttpURLLoad("overscroll/div-overscroll.html");
8042 FrameTestHelpers::WebViewHelper webViewHelper
;
8043 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/div-overscroll.html", true, 0, &client
, configureAndroid
);
8045 ScrollBegin(&webViewHelper
);
8047 // Scroll the Div to the end.
8048 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8049 ScrollUpdate(&webViewHelper
, 0, -316);
8050 Mock::VerifyAndClearExpectations(&client
);
8052 // Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
8053 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, 100), WebFloatSize(0, 100), WebFloatPoint(100, 100), WebFloatSize()));
8054 ScrollUpdate(&webViewHelper
, 0, -100);
8055 Mock::VerifyAndClearExpectations(&client
);
8057 // Page scrolls vertically, but over-scrolls horizontally.
8058 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-100, 0), WebFloatSize(-100, 0), WebFloatPoint(100, 100), WebFloatSize()));
8059 ScrollUpdate(&webViewHelper
, 100, 50);
8060 Mock::VerifyAndClearExpectations(&client
);
8062 // Scrolling up, Overscroll is not reported.
8063 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8064 ScrollUpdate(&webViewHelper
, 0, -50);
8065 Mock::VerifyAndClearExpectations(&client
);
8067 // Page scrolls horizontally, but over-scrolls vertically.
8068 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, 100), WebFloatSize(0, 100), WebFloatPoint(100, 100), WebFloatSize()));
8069 ScrollUpdate(&webViewHelper
, -100, -100);
8070 Mock::VerifyAndClearExpectations(&client
);
8073 TEST_F(WebFrameOverscrollTest
, RootLayerOverscrolledOnInnerDivOverScroll
)
8075 OverscrollWebViewClient client
;
8076 registerMockedHttpURLLoad("overscroll/div-overscroll.html");
8077 FrameTestHelpers::WebViewHelper webViewHelper
;
8078 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/div-overscroll.html", true, 0, &client
, configureAndroid
);
8080 ScrollBegin(&webViewHelper
);
8082 // Scroll the Div to the end.
8083 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8084 ScrollUpdate(&webViewHelper
, 0, -316);
8085 Mock::VerifyAndClearExpectations(&client
);
8087 // Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
8088 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50), WebFloatPoint(100, 100), WebFloatSize()));
8089 ScrollUpdate(&webViewHelper
, 0, -50);
8090 Mock::VerifyAndClearExpectations(&client
);
8093 TEST_F(WebFrameOverscrollTest
, RootLayerOverscrolledOnInnerIFrameOverScroll
)
8095 OverscrollWebViewClient client
;
8096 registerMockedHttpURLLoad("overscroll/iframe-overscroll.html");
8097 registerMockedHttpURLLoad("overscroll/scrollable-iframe.html");
8098 FrameTestHelpers::WebViewHelper webViewHelper
;
8099 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/iframe-overscroll.html", true, 0, &client
, configureAndroid
);
8101 ScrollBegin(&webViewHelper
);
8102 // Scroll the IFrame to the end.
8103 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8104 ScrollUpdate(&webViewHelper
, 0, -320);
8105 Mock::VerifyAndClearExpectations(&client
);
8107 // Now On Scrolling IFrame, scroll is bubbled and root layer is over-scrolled.
8108 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50), WebFloatPoint(100, 100), WebFloatSize()));
8109 ScrollUpdate(&webViewHelper
, 0, -50);
8110 Mock::VerifyAndClearExpectations(&client
);
8113 TEST_F(WebFrameOverscrollTest
, ScaledPageRootLayerOverscrolled
)
8115 OverscrollWebViewClient client
;
8116 registerMockedHttpURLLoad("overscroll/overscroll.html");
8117 FrameTestHelpers::WebViewHelper webViewHelper
;
8118 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/overscroll.html", true, 0, &client
, configureAndroid
);
8119 webViewImpl
->setPageScaleFactor(3.0);
8121 // Calculation of accumulatedRootOverscroll and unusedDelta on scaled page.
8122 ScrollBegin(&webViewHelper
);
8123 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, -10), WebFloatSize(0, -10), WebFloatPoint(33, 33), WebFloatSize()));
8124 ScrollUpdate(&webViewHelper
, 0, 30);
8125 Mock::VerifyAndClearExpectations(&client
);
8127 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, -10), WebFloatSize(0, -20), WebFloatPoint(33, 33), WebFloatSize()));
8128 ScrollUpdate(&webViewHelper
, 0, 30);
8129 Mock::VerifyAndClearExpectations(&client
);
8131 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-10, -10), WebFloatSize(-10, -30), WebFloatPoint(33, 33), WebFloatSize()));
8132 ScrollUpdate(&webViewHelper
, 30, 30);
8133 Mock::VerifyAndClearExpectations(&client
);
8135 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-10, 0), WebFloatSize(-20, -30), WebFloatPoint(33, 33), WebFloatSize()));
8136 ScrollUpdate(&webViewHelper
, 30, 0);
8137 Mock::VerifyAndClearExpectations(&client
);
8139 // Overscroll is not reported.
8140 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8141 ScrollEnd(&webViewHelper
);
8142 Mock::VerifyAndClearExpectations(&client
);
8145 TEST_F(WebFrameOverscrollTest
, NoOverscrollForSmallvalues
)
8147 OverscrollWebViewClient client
;
8148 registerMockedHttpURLLoad("overscroll/overscroll.html");
8149 FrameTestHelpers::WebViewHelper webViewHelper
;
8150 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/overscroll.html", true, 0, &client
, configureAndroid
);
8152 ScrollBegin(&webViewHelper
);
8153 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-10, -10), WebFloatSize(-10, -10), WebFloatPoint(100, 100), WebFloatSize()));
8154 ScrollUpdate(&webViewHelper
, 10, 10);
8155 Mock::VerifyAndClearExpectations(&client
);
8157 EXPECT_CALL(client
, didOverscroll(WebFloatSize(0, -0.10), WebFloatSize(-10, -10.10), WebFloatPoint(100, 100), WebFloatSize()));
8158 ScrollUpdate(&webViewHelper
, 0, 0.10);
8159 Mock::VerifyAndClearExpectations(&client
);
8161 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-0.10, 0), WebFloatSize(-10.10, -10.10), WebFloatPoint(100, 100), WebFloatSize()));
8162 ScrollUpdate(&webViewHelper
, 0.10, 0);
8163 Mock::VerifyAndClearExpectations(&client
);
8165 // For residual values overscrollDelta should be reset and didOverscroll shouldn't be called.
8166 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8167 ScrollUpdate(&webViewHelper
, 0, 0.09);
8168 Mock::VerifyAndClearExpectations(&client
);
8170 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8171 ScrollUpdate(&webViewHelper
, 0.09, 0.09);
8172 Mock::VerifyAndClearExpectations(&client
);
8174 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8175 ScrollUpdate(&webViewHelper
, 0.09, 0);
8176 Mock::VerifyAndClearExpectations(&client
);
8178 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8179 ScrollUpdate(&webViewHelper
, 0, -0.09);
8180 Mock::VerifyAndClearExpectations(&client
);
8182 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8183 ScrollUpdate(&webViewHelper
, -0.09, -0.09);
8184 Mock::VerifyAndClearExpectations(&client
);
8186 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8187 ScrollUpdate(&webViewHelper
, -0.09, 0);
8188 Mock::VerifyAndClearExpectations(&client
);
8190 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8191 ScrollEnd(&webViewHelper
);
8192 Mock::VerifyAndClearExpectations(&client
);
8195 TEST_F(WebFrameOverscrollTest
, ReportingLatestOverscrollForElasticOverscroll
)
8197 OverscrollWebViewClient client
;
8198 registerMockedHttpURLLoad("overscroll/overscroll.html");
8199 FrameTestHelpers::WebViewHelper webViewHelper
;
8200 webViewHelper
.initializeAndLoad(m_baseURL
+ "overscroll/overscroll.html", true, 0, &client
, configureAndroid
);
8202 // On disabling ReportWheelOverscroll, overscroll is not reported on MouseWheel.
8203 webViewHelper
.webView()->settings()->setReportWheelOverscroll(false);
8204 EXPECT_CALL(client
, didOverscroll(_
, _
, _
, _
)).Times(0);
8205 ScrollByWheel(&webViewHelper
, 10, 10, 1000, 1000);
8206 Mock::VerifyAndClearExpectations(&client
);
8208 // On enabling ReportWheelOverscroll, overscroll is reported on MouseWheel.
8209 webViewHelper
.webView()->settings()->setReportWheelOverscroll(true);
8210 EXPECT_CALL(client
, didOverscroll(WebFloatSize(-1000, -1000), WebFloatSize(-1000, -1000), WebFloatPoint(), WebFloatSize()));
8211 ScrollByWheel(&webViewHelper
, 10, 10, 1000, 1000);
8212 Mock::VerifyAndClearExpectations(&client
);
8215 TEST_F(WebFrameTest
, OrientationFrameDetach
)
8217 RuntimeEnabledFeatures::setOrientationEventEnabled(true);
8218 registerMockedHttpURLLoad("orientation-frame-detach.html");
8219 FrameTestHelpers::WebViewHelper webViewHelper
;
8220 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "orientation-frame-detach.html", true);
8221 webViewImpl
->mainFrameImpl()->sendOrientationChangeEvent();
8224 TEST_F(WebFrameTest
, MaxFramesDetach
)
8226 registerMockedHttpURLLoad("max-frames-detach.html");
8227 FrameTestHelpers::WebViewHelper webViewHelper
;
8228 WebViewImpl
* webViewImpl
= webViewHelper
.initializeAndLoad(m_baseURL
+ "max-frames-detach.html", true);
8229 webViewImpl
->mainFrameImpl()->collectGarbage();
8232 } // namespace blink