blob: ee7d58d8ea3414a201b01b71cb7ee1acfcd25388 [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 "headless/test/tab_socket_test.h"
#include "headless/public/headless_devtools_client.h"
#include "headless/public/headless_tab_socket.h"
namespace headless {
TabSocketTest::TabSocketTest() = default;
TabSocketTest::~TabSocketTest() = default;
void TabSocketTest::SetUp() {
options()->mojo_service_names.insert("headless::TabSocket");
HeadlessAsyncDevTooledBrowserTest::SetUp();
}
void TabSocketTest::RunDevTooledTest() {
devtools_client_->GetRuntime()->AddObserver(this);
devtools_client_->GetRuntime()->Enable();
// Note we must enable the page domain or the browser won't get told the
// devtools frame ids.
devtools_client_->GetPage()->AddObserver(this);
devtools_client_->GetPage()->Enable(
page::EnableParams::Builder().Build(),
base::BindOnce(&TabSocketTest::OnPageEnabled, base::Unretained(this)));
}
void TabSocketTest::OnPageEnabled(std::unique_ptr<page::EnableResult> result) {
devtools_client_->GetPage()->GetExperimental()->GetResourceTree(
page::GetResourceTreeParams::Builder().Build(),
base::BindOnce(&TabSocketTest::OnResourceTree, base::Unretained(this)));
}
void TabSocketTest::OnResourceTree(
std::unique_ptr<page::GetResourceTreeResult> result) {
main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId();
RunTabSocketTest();
}
void TabSocketTest::OnExecutionContextCreated(
const runtime::ExecutionContextCreatedParams& params) {
const base::DictionaryValue* dictionary;
bool is_main_world;
if (params.GetContext()->HasAuxData() &&
params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary)) {
if (dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) {
world_name_to_v8_execution_context_id_[params.GetContext()->GetName()] =
params.GetContext()->GetId();
}
std::string frame_id;
if (dictionary->GetString("frameId", &frame_id)) {
frame_id_to_v8_execution_context_ids_[frame_id].insert(
params.GetContext()->GetId());
}
}
}
void TabSocketTest::ExpectJsException(
std::unique_ptr<runtime::EvaluateResult> result) {
EXPECT_TRUE(result->HasExceptionDetails());
FinishAsynchronousTest();
}
void TabSocketTest::FailOnJsEvaluateException(
std::unique_ptr<runtime::EvaluateResult> result) {
if (!result->HasExceptionDetails())
return;
FinishAsynchronousTest();
const runtime::ExceptionDetails* exception_details =
result->GetExceptionDetails();
FAIL() << exception_details->GetText()
<< (exception_details->HasException()
? exception_details->GetException()->GetDescription().c_str()
: "");
}
bool TabSocketTest::GetAllowTabSockets() {
return true;
}
int TabSocketTest::GetV8ExecutionContextIdByWorldName(const std::string& name) {
const auto find_it = world_name_to_v8_execution_context_id_.find(name);
if (find_it == world_name_to_v8_execution_context_id_.end()) {
FinishAsynchronousTest();
CHECK(false) << "Unknown isolated world: " << name;
return -1;
}
return find_it->second;
}
const std::set<int>* TabSocketTest::GetV8ExecutionContextIdsForFrame(
const std::string& devtools_frame_id) const {
const auto find_it =
frame_id_to_v8_execution_context_ids_.find(devtools_frame_id);
if (find_it == frame_id_to_v8_execution_context_ids_.end())
return nullptr;
return &find_it->second;
}
void TabSocketTest::CreateMainWorldTabSocket(
std::string devtools_frame_id,
base::OnceCallback<void(int)> callback) {
const auto find_it =
frame_id_to_v8_execution_context_ids_.find(devtools_frame_id);
CHECK(find_it != frame_id_to_v8_execution_context_ids_.end());
if (find_it->second.size() != 1u) {
FinishAsynchronousTest();
FAIL() << "More than one v8 execution context exists for the main frame!";
}
InstallHeadlessTabSocketBindings(std::move(callback),
*find_it->second.begin());
}
void TabSocketTest::CreateIsolatedWorldTabSocket(
std::string isolated_world_name,
std::string devtools_frame_id,
base::OnceCallback<void(int)> callback) {
devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld(
page::CreateIsolatedWorldParams::Builder()
.SetFrameId(devtools_frame_id)
.SetWorldName(isolated_world_name)
.Build(),
base::BindOnce(&TabSocketTest::OnCreatedIsolatedWorld,
base::Unretained(this), std::move(callback)));
}
void TabSocketTest::OnCreatedIsolatedWorld(
base::OnceCallback<void(int)> callback,
std::unique_ptr<page::CreateIsolatedWorldResult> result) {
InstallHeadlessTabSocketBindings(std::move(callback),
result->GetExecutionContextId());
}
void TabSocketTest::InstallHeadlessTabSocketBindings(
base::OnceCallback<void(int)> callback,
int execution_context_id) {
HeadlessTabSocket* tab_socket = web_contents_->GetHeadlessTabSocket();
CHECK(tab_socket);
tab_socket->InstallHeadlessTabSocketBindings(
execution_context_id,
base::BindOnce(&TabSocketTest::OnInstalledHeadlessTabSocketBindings,
base::Unretained(this), execution_context_id,
std::move(callback)));
}
void TabSocketTest::OnInstalledHeadlessTabSocketBindings(
int execution_context_id,
base::OnceCallback<void(int)> callback,
bool success) {
if (!success) {
FinishAsynchronousTest();
CHECK(false) << "InstallHeadlessTabSocketBindings failed";
}
std::move(callback).Run(execution_context_id);
}
} // namespace headless