blob: da509e0916295cdd25b570518baf21095c6fe2c4 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/network/network_state_notifier.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#if defined(OS_MAC)
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/blink/public/mojom/input/text_input_host.mojom-blink.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
#endif
namespace blink {
namespace {
void DisableLazyLoadInSettings(Settings& settings) {
settings.SetLazyLoadEnabled(false);
}
void EnableLazyLoadInSettings(Settings& settings) {
settings.SetLazyLoadEnabled(true);
}
#if defined(OS_MAC)
void RegisterMockedHttpURLLoad(const std::string& base_url,
const std::string& file_name) {
url_test_helpers::RegisterMockedURLLoadFromBase(
WebString::FromUTF8(base_url), test::CoreTestDataPath(),
WebString::FromUTF8(file_name));
}
class TestTextInputHostWaiter : public mojom::blink::TextInputHost {
public:
TestTextInputHostWaiter() = default;
~TestTextInputHostWaiter() override = default;
void Init(base::OnceClosure callback,
blink::BrowserInterfaceBrokerProxy& provider) {
callback_ = std::move(callback);
provider.SetBinderForTesting(
mojom::blink::TextInputHost::Name_,
base::BindRepeating(&TestTextInputHostWaiter::BindTextInputHostReceiver,
base::Unretained(this)));
}
void GotCharacterIndexAtPoint(uint32_t index) override {
index_ = index;
if (callback_)
std::move(callback_).Run();
}
void GotFirstRectForRange(const gfx::Rect& rect) override {}
void BindTextInputHostReceiver(
mojo::ScopedMessagePipeHandle message_pipe_handle) {
receiver_.Bind(mojo::PendingReceiver<mojom::blink::TextInputHost>(
std::move(message_pipe_handle)));
}
uint32_t index() { return index_; }
private:
mojo::Receiver<mojom::blink::TextInputHost> receiver_{this};
uint32_t index_;
base::OnceClosure callback_;
};
#endif
} // namespace
class LocalFrameTest : public testing::Test {
public:
void TearDown() override {
// Reset the global data saver setting to false at the end of the test.
GetNetworkStateNotifier().SetSaveDataEnabled(false);
}
};
TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithFeatureDisabled) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&EnableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kDisabled,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithSettingDisabled) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&DisableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kDisabled,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWithAutomaticDisabled) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
ScopedAutomaticLazyImageLoadingForTest
scoped_automatic_lazy_image_loading_for_test(false);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&EnableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kEnabledExplicit,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
TEST_F(LocalFrameTest, IsLazyLoadingImageAllowedWhenNotRestricted) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
ScopedAutomaticLazyImageLoadingForTest
scoped_automatic_lazy_image_loading_for_test(true);
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(
false);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&EnableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kEnabledAutomatic,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
TEST_F(LocalFrameTest,
IsLazyLoadingImageAllowedWhenRestrictedWithDataSaverDisabled) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
ScopedAutomaticLazyImageLoadingForTest
scoped_automatic_lazy_image_loading_for_test(true);
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(true);
GetNetworkStateNotifier().SetSaveDataEnabled(false);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&EnableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kEnabledExplicit,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
TEST_F(LocalFrameTest,
IsLazyLoadingImageAllowedWhenRestrictedWithDataSaverEnabled) {
ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true);
ScopedAutomaticLazyImageLoadingForTest
scoped_automatic_lazy_image_loading_for_test(true);
ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest
scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test(true);
GetNetworkStateNotifier().SetSaveDataEnabled(true);
auto page_holder = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr,
base::BindOnce(&EnableLazyLoadInSettings));
EXPECT_EQ(LocalFrame::LazyLoadImageSetting::kEnabledAutomatic,
page_holder->GetFrame().GetLazyLoadImageSetting());
}
namespace {
void TestGreenDiv(DummyPageHolder& page_holder) {
const Document& doc = page_holder.GetDocument();
Element* div = doc.getElementById("div");
ASSERT_TRUE(div);
ASSERT_TRUE(div->GetComputedStyle());
EXPECT_EQ(MakeRGB(0, 128, 0), div->GetComputedStyle()->VisitedDependentColor(
GetCSSPropertyColor()));
}
} // namespace
TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLStyleInBody) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
data->Append(
"<html xmlns='http://www.w3.org/1999/xhtml'><body><style>div { color: "
"green }</style><div id='div'></div></body></html>",
static_cast<size_t>(118));
page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
TestGreenDiv(*page_holder);
}
TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLLinkInBody) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
data->Append(
"<html xmlns='http://www.w3.org/1999/xhtml'><body><link rel='stylesheet' "
"href='data:text/css,div{color:green}' /><div "
"id='div'></div></body></html>",
static_cast<size_t>(146));
page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
TestGreenDiv(*page_holder);
}
TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLStyleInHead) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
data->Append(
"<html xmlns='http://www.w3.org/1999/xhtml'><head><style>div { color: "
"green }</style></head><body><div id='div'></div></body></html>",
static_cast<size_t>(131));
page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
TestGreenDiv(*page_holder);
}
TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XHTMLLinkInHead) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
data->Append(
"<html xmlns='http://www.w3.org/1999/xhtml'><head><link rel='stylesheet' "
"href='data:text/css,div{color:green}' /></head><body><div "
"id='div'></div></body></html>",
static_cast<size_t>(159));
page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
TestGreenDiv(*page_holder);
}
TEST_F(LocalFrameTest, ForceSynchronousDocumentInstall_XMLStyleSheet) {
auto page_holder = std::make_unique<DummyPageHolder>(IntSize(800, 600));
scoped_refptr<SharedBuffer> data = SharedBuffer::Create();
data->Append(
"<?xml-stylesheet type='text/css' "
"href='data:text/css,div{color:green}'?><html "
"xmlns='http://www.w3.org/1999/xhtml'><body><div "
"id='div'></div></body></html>",
static_cast<size_t>(155));
page_holder->GetFrame().ForceSynchronousDocumentInstall("text/xml", data);
TestGreenDiv(*page_holder);
}
#if defined(OS_MAC)
TEST_F(LocalFrameTest, CharacterIndexAtPointWithPinchZoom) {
RegisterMockedHttpURLLoad("http://internal.test/", "sometext.html");
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.InitializeAndLoad("http://internal.test/sometext.html");
web_view_helper.LoadAhem();
web_view_helper.Resize(gfx::Size(640, 480));
// Move the visual viewport to the start of the target div containing the
// text.
web_view_helper.GetWebView()->SetPageScaleFactor(2);
web_view_helper.GetWebView()->SetVisualViewportOffset(gfx::PointF(100, 50));
Page* page = web_view_helper.GetWebView()->GetPage();
LocalFrame* main_frame = DynamicTo<LocalFrame>(page->MainFrame());
main_frame->text_input_host_.reset();
base::RunLoop run_loop;
TestTextInputHostWaiter waiter;
waiter.Init(run_loop.QuitClosure(), main_frame->GetBrowserInterfaceBroker());
main_frame->GetBrowserInterfaceBroker().GetInterface(
main_frame->text_input_host_.BindNewPipeAndPassReceiver(
main_frame->GetTaskRunner(blink::TaskType::kInternalDefault)));
// Since we're zoomed in to 2X, each char of Ahem is 20px wide/tall in
// viewport space. We expect to hit the fifth char on the first line.
main_frame->GetCharacterIndexAtPoint(gfx::Point(100, 15));
run_loop.Run();
EXPECT_EQ(waiter.index(), 5ul);
}
#endif
} // namespace blink