blob: 3dee0055e43af97671e279ff6a7d07b1617ca761 [file] [log] [blame]
// Copyright 2017 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/testing/page_test_base.h"
#include "base/callback.h"
#include "base/test/bind_test_util.h"
#include "base/time/default_tick_clock.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/string_or_array_buffer_or_array_buffer_view.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_font_face_descriptors.h"
#include "third_party/blink/renderer/core/css/font_face_set_document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/html_collection.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
namespace blink {
namespace {
Element* GetOrCreateElement(ContainerNode* parent,
const HTMLQualifiedName& tag_name) {
HTMLCollection* elements = parent->getElementsByTagNameNS(
tag_name.NamespaceURI(), tag_name.LocalName());
if (!elements->IsEmpty())
return elements->item(0);
return parent->ownerDocument()->CreateRawElement(
tag_name, CreateElementFlags::ByCreateElement());
}
} // namespace
PageTestBase::MockClipboardHostProvider::MockClipboardHostProvider(
blink::BrowserInterfaceBrokerProxy& interface_broker) {
Install(interface_broker);
}
PageTestBase::MockClipboardHostProvider::MockClipboardHostProvider() = default;
PageTestBase::MockClipboardHostProvider::~MockClipboardHostProvider() {
if (interface_broker_) {
interface_broker_->SetBinderForTesting(
blink::mojom::blink::ClipboardHost::Name_, {});
}
}
void PageTestBase::MockClipboardHostProvider::Install(
blink::BrowserInterfaceBrokerProxy& interface_broker) {
interface_broker_ = &interface_broker;
interface_broker_->SetBinderForTesting(
blink::mojom::blink::ClipboardHost::Name_,
base::BindRepeating(
&PageTestBase::MockClipboardHostProvider::BindClipboardHost,
base::Unretained(this)));
}
void PageTestBase::MockClipboardHostProvider::BindClipboardHost(
mojo::ScopedMessagePipeHandle handle) {
host_.Bind(mojo::PendingReceiver<blink::mojom::blink::ClipboardHost>(
std::move(handle)));
}
PageTestBase::PageTestBase() = default;
PageTestBase::~PageTestBase() = default;
void PageTestBase::EnableCompositing() {
DCHECK(!dummy_page_holder_)
<< "EnableCompositing() must be called before set up";
enable_compositing_ = true;
}
void PageTestBase::SetUp() {
DCHECK(!dummy_page_holder_) << "Page should be set up only once";
auto setter = base::BindLambdaForTesting([&](Settings& settings) {
if (enable_compositing_)
settings.SetAcceleratedCompositingEnabled(true);
});
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
IntSize(800, 600), nullptr, nullptr, std::move(setter), GetTickClock());
// Mock out clipboard calls so that tests don't mess
// with each other's copies/pastes when running in parallel.
mock_clipboard_host_provider_.Install(GetFrame().GetBrowserInterfaceBroker());
// Use no-quirks (ake "strict") mode by default.
GetDocument().SetCompatibilityMode(Document::kNoQuirksMode);
// Use desktop page scale limits by default.
GetPage().SetDefaultPageScaleLimits(1, 4);
}
void PageTestBase::SetUp(IntSize size) {
DCHECK(!dummy_page_holder_) << "Page should be set up only once";
auto setter = base::BindLambdaForTesting([&](Settings& settings) {
if (enable_compositing_)
settings.SetAcceleratedCompositingEnabled(true);
});
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
size, nullptr, nullptr, std::move(setter), GetTickClock());
// Use no-quirks (ake "strict") mode by default.
GetDocument().SetCompatibilityMode(Document::kNoQuirksMode);
// Use desktop page scale limits by default.
GetPage().SetDefaultPageScaleLimits(1, 4);
}
void PageTestBase::SetupPageWithClients(
Page::PageClients* clients,
LocalFrameClient* local_frame_client,
FrameSettingOverrideFunction setting_overrider) {
DCHECK(!dummy_page_holder_) << "Page should be set up only once";
auto setter = base::BindLambdaForTesting([&](Settings& settings) {
if (setting_overrider)
setting_overrider(settings);
if (enable_compositing_)
settings.SetAcceleratedCompositingEnabled(true);
});
dummy_page_holder_ = std::make_unique<DummyPageHolder>(
IntSize(800, 600), clients, local_frame_client, std::move(setter),
GetTickClock());
// Use no-quirks (ake "strict") mode by default.
GetDocument().SetCompatibilityMode(Document::kNoQuirksMode);
// Use desktop page scale limits by default.
GetPage().SetDefaultPageScaleLimits(1, 4);
}
void PageTestBase::TearDown() {
dummy_page_holder_ = nullptr;
}
Document& PageTestBase::GetDocument() const {
return dummy_page_holder_->GetDocument();
}
Page& PageTestBase::GetPage() const {
return dummy_page_holder_->GetPage();
}
LocalFrame& PageTestBase::GetFrame() const {
return GetDummyPageHolder().GetFrame();
}
FrameSelection& PageTestBase::Selection() const {
return GetFrame().Selection();
}
void PageTestBase::LoadAhem() {
LoadAhem(GetFrame());
}
void PageTestBase::LoadAhem(LocalFrame& frame) {
Document& document = *frame.DomWindow()->document();
scoped_refptr<SharedBuffer> shared_buffer =
test::ReadFromFile(test::CoreTestDataPath("Ahem.ttf"));
StringOrArrayBufferOrArrayBufferView buffer =
StringOrArrayBufferOrArrayBufferView::FromArrayBuffer(
DOMArrayBuffer::Create(shared_buffer));
FontFace* ahem = FontFace::Create(frame.DomWindow(), "Ahem", buffer,
FontFaceDescriptors::Create());
ScriptState* script_state = ToScriptStateForMainWorld(&frame);
DummyExceptionStateForTesting exception_state;
FontFaceSetDocument::From(document)->addForBinding(script_state, ahem,
exception_state);
}
// Both sets the inner html and runs the document lifecycle.
void PageTestBase::SetBodyInnerHTML(const String& body_content) {
GetDocument().body()->setInnerHTML(body_content, ASSERT_NO_EXCEPTION);
UpdateAllLifecyclePhasesForTest();
}
void PageTestBase::SetBodyContent(const std::string& body_content) {
SetBodyInnerHTML(String::FromUTF8(body_content));
}
void PageTestBase::SetHtmlInnerHTML(const std::string& html_content) {
GetDocument().documentElement()->setInnerHTML(String::FromUTF8(html_content));
UpdateAllLifecyclePhasesForTest();
}
void PageTestBase::InsertStyleElement(const std::string& style_rules) {
Element* const head =
GetOrCreateElement(&GetDocument(), html_names::kHeadTag);
DCHECK_EQ(head, GetOrCreateElement(&GetDocument(), html_names::kHeadTag));
Element* const style = GetDocument().CreateRawElement(
html_names::kStyleTag, CreateElementFlags::ByCreateElement());
style->setTextContent(String(style_rules.data(), style_rules.size()));
head->appendChild(style);
}
void PageTestBase::NavigateTo(const KURL& url,
const WTF::HashMap<String, String>& headers) {
auto params =
WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url);
for (const auto& header : headers)
params->response.SetHttpHeaderField(header.key, header.value);
GetFrame().Loader().CommitNavigation(std::move(params),
nullptr /* extra_data */);
blink::test::RunPendingTasks();
ASSERT_EQ(url.GetString(), GetDocument().Url().GetString());
}
void PageTestBase::UpdateAllLifecyclePhasesForTest() {
GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
GetDocument().View()->RunPostLifecycleSteps();
}
StyleEngine& PageTestBase::GetStyleEngine() {
return GetDocument().GetStyleEngine();
}
Element* PageTestBase::GetElementById(const char* id) const {
return GetDocument().getElementById(id);
}
AnimationClock& PageTestBase::GetAnimationClock() {
return GetDocument().GetAnimationClock();
}
PendingAnimations& PageTestBase::GetPendingAnimations() {
return GetDocument().GetPendingAnimations();
}
FocusController& PageTestBase::GetFocusController() const {
return GetDocument().GetPage()->GetFocusController();
}
void PageTestBase::EnablePlatform() {
DCHECK(!platform_);
platform_ = std::make_unique<
ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>>();
}
const base::TickClock* PageTestBase::GetTickClock() {
return platform_ ? platform()->test_task_runner()->GetMockTickClock()
: base::DefaultTickClock::GetInstance();
}
} // namespace blink