blob: e7f6691c0e7cca1d294f37d4968f56f21bf1ba39 [file] [log] [blame]
// Copyright 2016 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 "content/shell/test_runner/test_runner_for_specific_view.h"
#include <stddef.h>
#include <limits>
#include <utility>
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
#include "cc/paint/paint_canvas.h"
#include "content/renderer/gpu/layer_tree_view.h"
#include "content/shell/test_runner/layout_and_paint_async_then.h"
#include "content/shell/test_runner/layout_dump.h"
#include "content/shell/test_runner/mock_content_settings_client.h"
#include "content/shell/test_runner/mock_screen_orientation_client.h"
#include "content/shell/test_runner/pixel_dump.h"
#include "content/shell/test_runner/spell_check_client.h"
#include "content/shell/test_runner/test_common.h"
#include "content/shell/test_runner/test_interfaces.h"
#include "content/shell/test_runner/test_preferences.h"
#include "content/shell/test_runner/test_runner.h"
#include "content/shell/test_runner/web_test_delegate.h"
#include "content/shell/test_runner/web_view_test_proxy.h"
#include "gin/arguments.h"
#include "gin/array_buffer.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_array_buffer.h"
#include "third_party/blink/public/web/web_array_buffer_converter.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_security_policy.h"
#include "third_party/blink/public/web/web_serialized_script_value.h"
#include "third_party/blink/public/web/web_settings.h"
#include "third_party/blink/public/web/web_surrounding_text.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/switches.h"
namespace test_runner {
TestRunnerForSpecificView::TestRunnerForSpecificView(
WebViewTestProxy* web_view_test_proxy)
: web_view_test_proxy_(web_view_test_proxy), weak_factory_(this) {
Reset();
}
TestRunnerForSpecificView::~TestRunnerForSpecificView() {}
void TestRunnerForSpecificView::Install(blink::WebLocalFrame* frame) {
web_view_test_proxy_->test_interfaces()->GetTestRunner()->Install(
frame, weak_factory_.GetWeakPtr());
}
void TestRunnerForSpecificView::Reset() {
pointer_locked_ = false;
pointer_lock_planned_result_ = PointerLockWillSucceed;
if (!web_view() || !web_view()->MainFrame())
return;
RemoveWebPageOverlay();
SetTabKeyCyclesThroughElements(true);
#if !defined(OS_MACOSX) && !defined(OS_WIN)
// (Constants copied because we can't depend on the header that defined
// them from this file.)
web_view()->SetSelectionColors(0xff1e90ff, 0xff000000, 0xffc8c8c8,
0xff323232);
#endif
if (web_view()->MainFrame()->IsWebLocalFrame()) {
web_view()->MainFrame()->ToWebLocalFrame()->EnableViewSourceMode(false);
web_view()->SetTextZoomFactor(1);
web_view()->SetZoomLevel(0);
// As would the browser via IPC, set visibility on the RenderWidget then on
// the Page.
// TODO(danakj): This should set visibility on all RenderWidgets not just
// the main frame.
// TODO(danakj): This should set visible on the RenderWidget not just the
// LayerTreeView.
main_frame_render_widget()->layer_tree_view()->SetVisible(true);
}
web_view_test_proxy_->ApplyPageHidden(/*hidden=*/false,
/*initial_setting=*/true);
}
bool TestRunnerForSpecificView::RequestPointerLock() {
switch (pointer_lock_planned_result_) {
case PointerLockWillSucceed:
PostTask(base::BindOnce(
&TestRunnerForSpecificView::DidAcquirePointerLockInternal,
weak_factory_.GetWeakPtr()));
return true;
case PointerLockWillRespondAsync:
DCHECK(!pointer_locked_);
return true;
case PointerLockWillFailSync:
DCHECK(!pointer_locked_);
return false;
default:
NOTREACHED();
return false;
}
}
void TestRunnerForSpecificView::RequestPointerUnlock() {
PostTask(
base::BindOnce(&TestRunnerForSpecificView::DidLosePointerLockInternal,
weak_factory_.GetWeakPtr()));
}
bool TestRunnerForSpecificView::isPointerLocked() {
return pointer_locked_;
}
void TestRunnerForSpecificView::PostTask(base::OnceClosure callback) {
delegate()->PostTask(std::move(callback));
}
void TestRunnerForSpecificView::PostV8Callback(
const v8::Local<v8::Function>& callback) {
PostTask(base::BindOnce(&TestRunnerForSpecificView::InvokeV8Callback,
weak_factory_.GetWeakPtr(),
v8::UniquePersistent<v8::Function>(
blink::MainThreadIsolate(), callback)));
}
void TestRunnerForSpecificView::PostV8CallbackWithArgs(
v8::UniquePersistent<v8::Function> callback,
int argc,
v8::Local<v8::Value> argv[]) {
std::vector<v8::UniquePersistent<v8::Value>> args;
for (int i = 0; i < argc; i++) {
args.push_back(
v8::UniquePersistent<v8::Value>(blink::MainThreadIsolate(), argv[i]));
}
PostTask(base::BindOnce(&TestRunnerForSpecificView::InvokeV8CallbackWithArgs,
weak_factory_.GetWeakPtr(), std::move(callback),
std::move(args)));
}
void TestRunnerForSpecificView::InvokeV8Callback(
const v8::UniquePersistent<v8::Function>& callback) {
std::vector<v8::UniquePersistent<v8::Value>> empty_args;
InvokeV8CallbackWithArgs(callback, std::move(empty_args));
}
void TestRunnerForSpecificView::InvokeV8CallbackWithArgs(
const v8::UniquePersistent<v8::Function>& callback,
const std::vector<v8::UniquePersistent<v8::Value>>& args) {
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
blink::WebLocalFrame* frame = GetLocalMainFrame();
v8::Local<v8::Context> context = frame->MainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
std::vector<v8::Local<v8::Value>> local_args;
for (const auto& arg : args) {
local_args.push_back(v8::Local<v8::Value>::New(isolate, arg));
}
frame->CallFunctionEvenIfScriptDisabled(
v8::Local<v8::Function>::New(isolate, callback), context->Global(),
local_args.size(), local_args.data());
}
base::OnceClosure TestRunnerForSpecificView::CreateClosureThatPostsV8Callback(
const v8::Local<v8::Function>& callback) {
return base::BindOnce(
&TestRunnerForSpecificView::PostTask, weak_factory_.GetWeakPtr(),
base::BindOnce(&TestRunnerForSpecificView::InvokeV8Callback,
weak_factory_.GetWeakPtr(),
v8::UniquePersistent<v8::Function>(
blink::MainThreadIsolate(), callback)));
}
void TestRunnerForSpecificView::UpdateAllLifecyclePhasesAndComposite() {
// Note, this is executed synchronously. Wrap in setTimeout() to run
// asynchronously.
blink::WebWidget* widget =
web_view()->MainFrame()->ToWebLocalFrame()->FrameWidget();
widget->UpdateAllLifecyclePhasesAndCompositeForTesting(/* raster = */ true);
}
void TestRunnerForSpecificView::UpdateAllLifecyclePhasesAndCompositeThen(
v8::Local<v8::Function> callback) {
// Note, this is executed synchronously. Wrap in setTimeout() to run
// asynchronously.
TestRunnerForSpecificView::UpdateAllLifecyclePhasesAndComposite();
InvokeV8Callback(
v8::UniquePersistent<v8::Function>(blink::MainThreadIsolate(), callback));
}
void TestRunnerForSpecificView::LayoutAndPaintAsync() {
// TODO(lfg, lukasza): TestRunnerForSpecificView assumes that there's a single
// WebWidget for the entire view, but with out-of-process iframes there may be
// multiple WebWidgets, one for each local root. We should look into making
// this structure more generic.
test_runner::LayoutAndPaintAsyncThen(
web_view()->MainFrame()->ToWebLocalFrame()->FrameWidget(),
base::DoNothing());
}
void TestRunnerForSpecificView::LayoutAndPaintAsyncThen(
v8::Local<v8::Function> callback) {
test_runner::LayoutAndPaintAsyncThen(
web_view()->MainFrame()->ToWebLocalFrame()->FrameWidget(),
CreateClosureThatPostsV8Callback(callback));
}
void TestRunnerForSpecificView::CapturePixelsAsyncThen(
v8::Local<v8::Function> callback) {
v8::UniquePersistent<v8::Function> persistent_callback(
blink::MainThreadIsolate(), callback);
CHECK(web_view()->MainFrame()->IsWebLocalFrame())
<< "Web tests harness doesn't currently support running "
<< "testRuner.capturePixelsAsyncThen from an OOPIF";
web_view_test_proxy_->test_interfaces()->GetTestRunner()->DumpPixelsAsync(
web_view()->MainFrame()->ToWebLocalFrame(),
base::BindOnce(&TestRunnerForSpecificView::CapturePixelsCallback,
weak_factory_.GetWeakPtr(),
std::move(persistent_callback)));
}
void TestRunnerForSpecificView::CapturePixelsCallback(
v8::UniquePersistent<v8::Function> callback,
const SkBitmap& snapshot) {
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
GetLocalMainFrame()->MainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
v8::Local<v8::Value> argv[3];
// Size can be 0 for cases where copyImageAt was called on position
// that doesn't have an image.
int width = snapshot.info().width();
argv[0] = v8::Number::New(isolate, width);
int height = snapshot.info().height();
argv[1] = v8::Number::New(isolate, height);
// Skia's internal byte order is platform-dependent. Always convert to RGBA
// in order to provide a consistent ordering to the web tests.
const SkImageInfo bufferInfo =
snapshot.info().makeColorType(kRGBA_8888_SkColorType);
const size_t bufferRowBytes = bufferInfo.minRowBytes();
blink::WebArrayBuffer buffer = blink::WebArrayBuffer::Create(
bufferInfo.computeByteSize(bufferRowBytes), 1);
if (!snapshot.readPixels(bufferInfo, buffer.Data(), bufferRowBytes, 0, 0)) {
// We only expect readPixels to fail for null bitmaps.
DCHECK(snapshot.isNull());
}
argv[2] = blink::WebArrayBufferConverter::ToV8Value(
&buffer, context->Global(), isolate);
PostV8CallbackWithArgs(std::move(callback), arraysize(argv), argv);
}
void TestRunnerForSpecificView::CopyImageAtAndCapturePixelsAsyncThen(
int x,
int y,
v8::Local<v8::Function> callback) {
v8::UniquePersistent<v8::Function> persistent_callback(
blink::MainThreadIsolate(), callback);
CopyImageAtAndCapturePixels(
web_view()->MainFrame()->ToWebLocalFrame(), x, y,
base::BindOnce(&TestRunnerForSpecificView::CapturePixelsCallback,
weak_factory_.GetWeakPtr(),
std::move(persistent_callback)));
}
void TestRunnerForSpecificView::GetManifestThen(
v8::Local<v8::Function> callback) {
if (!web_view()->MainFrame()->IsWebLocalFrame()) {
CHECK(false) << "This function cannot be called if the main frame is not a "
"local frame.";
}
v8::UniquePersistent<v8::Function> persistent_callback(
blink::MainThreadIsolate(), callback);
delegate()->FetchManifest(
web_view(),
base::BindOnce(&TestRunnerForSpecificView::GetManifestCallback,
weak_factory_.GetWeakPtr(),
std::move(persistent_callback)));
}
void TestRunnerForSpecificView::GetManifestCallback(
v8::UniquePersistent<v8::Function> callback,
const GURL& manifest_url,
const blink::Manifest& manifest) {
PostV8CallbackWithArgs(std::move(callback), 0, nullptr);
}
void TestRunnerForSpecificView::GetBluetoothManualChooserEvents(
v8::Local<v8::Function> callback) {
return delegate()->GetBluetoothManualChooserEvents(base::BindOnce(
&TestRunnerForSpecificView::GetBluetoothManualChooserEventsCallback,
weak_factory_.GetWeakPtr(),
v8::UniquePersistent<v8::Function>(blink::MainThreadIsolate(),
callback)));
}
void TestRunnerForSpecificView::GetBluetoothManualChooserEventsCallback(
v8::UniquePersistent<v8::Function> callback,
const std::vector<std::string>& events) {
// Build the V8 context.
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
GetLocalMainFrame()->MainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
// Convert the argument.
v8::Local<v8::Value> arg;
if (!gin::TryConvertToV8(isolate, events, &arg))
return;
// Call the callback.
PostV8CallbackWithArgs(std::move(callback), 1, &arg);
}
void TestRunnerForSpecificView::SetBluetoothFakeAdapter(
const std::string& adapter_name,
v8::Local<v8::Function> callback) {
delegate()->SetBluetoothFakeAdapter(
adapter_name, CreateClosureThatPostsV8Callback(callback));
}
void TestRunnerForSpecificView::SetBluetoothManualChooser(bool enable) {
delegate()->SetBluetoothManualChooser(enable);
}
void TestRunnerForSpecificView::SendBluetoothManualChooserEvent(
const std::string& event,
const std::string& argument) {
delegate()->SendBluetoothManualChooserEvent(event, argument);
}
void TestRunnerForSpecificView::SetBackingScaleFactor(
double value,
v8::Local<v8::Function> callback) {
delegate()->SetDeviceScaleFactor(value);
// TODO(oshima): remove this callback argument when all platforms are migrated
// to use-zoom-for-dsf by default
v8::UniquePersistent<v8::Function> global_callback(blink::MainThreadIsolate(),
callback);
v8::Local<v8::Value> arg = v8::Boolean::New(
blink::MainThreadIsolate(), delegate()->IsUseZoomForDSFEnabled());
PostV8CallbackWithArgs(std::move(global_callback), 1, &arg);
}
void TestRunnerForSpecificView::EnableUseZoomForDSF(
v8::Local<v8::Function> callback) {
delegate()->EnableUseZoomForDSF();
PostV8Callback(callback);
}
void TestRunnerForSpecificView::SetColorProfile(
const std::string& name,
v8::Local<v8::Function> callback) {
delegate()->SetDeviceColorSpace(name);
PostV8Callback(callback);
}
void TestRunnerForSpecificView::DispatchBeforeInstallPromptEvent(
const std::vector<std::string>& event_platforms,
v8::Local<v8::Function> callback) {
delegate()->DispatchBeforeInstallPromptEvent(
event_platforms,
base::BindOnce(
&TestRunnerForSpecificView::DispatchBeforeInstallPromptCallback,
weak_factory_.GetWeakPtr(),
v8::UniquePersistent<v8::Function>(blink::MainThreadIsolate(),
callback)));
}
void TestRunnerForSpecificView::DispatchBeforeInstallPromptCallback(
v8::UniquePersistent<v8::Function> callback,
bool canceled) {
v8::Isolate* isolate = blink::MainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context =
GetLocalMainFrame()->MainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
v8::Local<v8::Value> arg;
arg = v8::Boolean::New(isolate, canceled);
PostV8CallbackWithArgs(std::move(callback), 1, &arg);
}
void TestRunnerForSpecificView::RunIdleTasks(v8::Local<v8::Function> callback) {
delegate()->RunIdleTasks(CreateClosureThatPostsV8Callback(callback));
}
void TestRunnerForSpecificView::SetTabKeyCyclesThroughElements(
bool tab_key_cycles_through_elements) {
web_view()->SetTabKeyCyclesThroughElements(tab_key_cycles_through_elements);
}
void TestRunnerForSpecificView::ExecCommand(gin::Arguments* args) {
std::string command;
args->GetNext(&command);
std::string value;
if (args->Length() >= 3) {
// Ignore the second parameter (which is userInterface)
// since this command emulates a manual action.
args->Skip();
args->GetNext(&value);
}
// Note: webkit's version does not return the boolean, so neither do we.
web_view()->FocusedFrame()->ExecuteCommand(
blink::WebString::FromUTF8(command), blink::WebString::FromUTF8(value));
}
bool TestRunnerForSpecificView::IsCommandEnabled(const std::string& command) {
return web_view()->FocusedFrame()->IsCommandEnabled(
blink::WebString::FromUTF8(command));
}
bool TestRunnerForSpecificView::HasCustomPageSizeStyle(int page_index) {
// TODO(dcheng): This class has many implicit assumptions that the frames it
// operates on are always local.
blink::WebFrame* frame = web_view()->MainFrame();
if (!frame || frame->IsWebRemoteFrame())
return false;
return frame->ToWebLocalFrame()->HasCustomPageSizeStyle(page_index);
}
void TestRunnerForSpecificView::ForceRedSelectionColors() {
web_view()->SetSelectionColors(0xffee0000, 0xff00ee00, 0xff000000,
0xffc0c0c0);
}
void TestRunnerForSpecificView::SetPageVisibility(
const std::string& new_visibility) {
bool hidden;
if (new_visibility == "visible")
hidden = false;
else if (new_visibility == "hidden")
hidden = true;
else
return;
// As would the browser via IPC, set visibility on the RenderWidget then on
// the Page.
// TODO(danakj): This should set visibility on all RenderWidgets not just the
// main frame.
// TODO(danakj): This should set visible on the RenderWidget not just the
// LayerTreeView.
main_frame_render_widget()->layer_tree_view()->SetVisible(!hidden);
web_view_test_proxy_->ApplyPageHidden(/*hidden=*/hidden,
/*initial_setting=*/false);
}
void TestRunnerForSpecificView::SetTextDirection(
const std::string& direction_name) {
// Map a direction name to a WebTextDirection value.
blink::WebTextDirection direction;
if (direction_name == "auto")
direction = blink::kWebTextDirectionDefault;
else if (direction_name == "rtl")
direction = blink::kWebTextDirectionRightToLeft;
else if (direction_name == "ltr")
direction = blink::kWebTextDirectionLeftToRight;
else
return;
web_view()->FocusedFrame()->SetTextDirection(direction);
}
void TestRunnerForSpecificView::AddWebPageOverlay() {
web_view()->SetMainFrameOverlayColor(SK_ColorCYAN);
}
void TestRunnerForSpecificView::RemoveWebPageOverlay() {
web_view()->SetMainFrameOverlayColor(SK_ColorTRANSPARENT);
}
void TestRunnerForSpecificView::ForceNextWebGLContextCreationToFail() {
web_view()->ForceNextWebGLContextCreationToFail();
}
void TestRunnerForSpecificView::ForceNextDrawingBufferCreationToFail() {
web_view()->ForceNextDrawingBufferCreationToFail();
}
void TestRunnerForSpecificView::SetWindowIsKey(bool value) {
web_view_test_proxy_->test_interfaces()->GetTestRunner()->SetFocus(web_view(),
value);
}
void TestRunnerForSpecificView::DidAcquirePointerLock() {
DidAcquirePointerLockInternal();
}
void TestRunnerForSpecificView::DidNotAcquirePointerLock() {
DidNotAcquirePointerLockInternal();
}
void TestRunnerForSpecificView::DidLosePointerLock() {
DidLosePointerLockInternal();
}
void TestRunnerForSpecificView::SetPointerLockWillFailSynchronously() {
pointer_lock_planned_result_ = PointerLockWillFailSync;
}
void TestRunnerForSpecificView::SetPointerLockWillRespondAsynchronously() {
pointer_lock_planned_result_ = PointerLockWillRespondAsync;
}
void TestRunnerForSpecificView::DidAcquirePointerLockInternal() {
pointer_locked_ = true;
web_view()->MainFrameWidget()->DidAcquirePointerLock();
// Reset planned result to default.
pointer_lock_planned_result_ = PointerLockWillSucceed;
}
void TestRunnerForSpecificView::DidNotAcquirePointerLockInternal() {
DCHECK(!pointer_locked_);
pointer_locked_ = false;
web_view()->MainFrameWidget()->DidNotAcquirePointerLock();
// Reset planned result to default.
pointer_lock_planned_result_ = PointerLockWillSucceed;
}
void TestRunnerForSpecificView::DidLosePointerLockInternal() {
bool was_locked = pointer_locked_;
pointer_locked_ = false;
if (was_locked)
web_view()->MainFrameWidget()->DidLosePointerLock();
}
void TestRunnerForSpecificView::SetDomainRelaxationForbiddenForURLScheme(
bool forbidden,
const std::string& scheme) {
web_view()->SetDomainRelaxationForbidden(forbidden,
blink::WebString::FromUTF8(scheme));
}
v8::Local<v8::Value>
TestRunnerForSpecificView::EvaluateScriptInIsolatedWorldAndReturnValue(
int world_id,
const std::string& script) {
blink::WebScriptSource source(blink::WebString::FromUTF8(script));
// This relies on the iframe focusing itself when it loads. This is a bit
// sketchy, but it seems to be what other tests do.
v8::Local<v8::Value> value =
web_view()->FocusedFrame()->ExecuteScriptInIsolatedWorldAndReturnValue(
world_id, source);
if (!value.IsEmpty())
return value;
return v8::Local<v8::Value>();
}
void TestRunnerForSpecificView::EvaluateScriptInIsolatedWorld(
int world_id,
const std::string& script) {
blink::WebScriptSource source(blink::WebString::FromUTF8(script));
web_view()->FocusedFrame()->ExecuteScriptInIsolatedWorld(world_id, source);
}
void TestRunnerForSpecificView::SetIsolatedWorldSecurityOrigin(
int world_id,
v8::Local<v8::Value> origin) {
if (!(origin->IsString() || !origin->IsNull()))
return;
blink::WebSecurityOrigin web_origin;
if (origin->IsString()) {
web_origin = blink::WebSecurityOrigin::CreateFromString(V8StringToWebString(
blink::MainThreadIsolate(), origin.As<v8::String>()));
}
web_view()->FocusedFrame()->SetIsolatedWorldSecurityOrigin(world_id,
web_origin);
}
void TestRunnerForSpecificView::SetIsolatedWorldContentSecurityPolicy(
int world_id,
const std::string& policy) {
web_view()->FocusedFrame()->SetIsolatedWorldContentSecurityPolicy(
world_id, blink::WebString::FromUTF8(policy));
}
void TestRunner::InsertStyleSheet(const std::string& source_code) {
blink::WebLocalFrame::FrameForCurrentContext()
->GetDocument()
.InsertStyleSheet(blink::WebString::FromUTF8(source_code));
}
bool TestRunnerForSpecificView::FindString(
const std::string& search_text,
const std::vector<std::string>& options_array) {
bool match_case = true;
bool forward = true;
bool find_next = true;
bool wrap_around = false;
for (const std::string& option : options_array) {
if (option == "CaseInsensitive")
match_case = false;
else if (option == "Backwards")
forward = false;
else if (option == "StartInSelection")
find_next = false;
else if (option == "WrapAround")
wrap_around = true;
}
blink::WebLocalFrame* frame = GetLocalMainFrame();
const bool find_result = frame->FindForTesting(
0, blink::WebString::FromUTF8(search_text), match_case, forward,
find_next, false /* force */, wrap_around);
return find_result;
}
std::string TestRunnerForSpecificView::SelectionAsMarkup() {
return GetLocalMainFrame()->SelectionAsMarkup().Utf8();
}
void TestRunnerForSpecificView::SetViewSourceForFrame(const std::string& name,
bool enabled) {
blink::WebFrame* target_frame =
GetLocalMainFrame()->FindFrameByName(blink::WebString::FromUTF8(name));
if (target_frame) {
CHECK(target_frame->IsWebLocalFrame())
<< "This function requires that the target frame is a local frame.";
target_frame->ToWebLocalFrame()->EnableViewSourceMode(enabled);
}
}
blink::WebLocalFrame* TestRunnerForSpecificView::GetLocalMainFrame() {
if (!web_view()->MainFrame()->IsWebLocalFrame()) {
// Hitting the check below uncovers a new scenario that requires OOPIF
// support in the web tests harness.
CHECK(false) << "This function cannot be called if the main frame is not a "
"local frame.";
}
return web_view()->MainFrame()->ToWebLocalFrame();
}
content::RenderWidget* TestRunnerForSpecificView::main_frame_render_widget() {
return web_view_test_proxy_->GetWidget();
}
blink::WebView* TestRunnerForSpecificView::web_view() {
// TODO(danakj): This could grab the GetWebView() off RenderViewImpl instead.
return web_view_test_proxy_->web_view();
}
WebTestDelegate* TestRunnerForSpecificView::delegate() {
return web_view_test_proxy_->delegate();
}
} // namespace test_runner