| Index: headless/test/headless_js_bindings_browsertest.cc
|
| diff --git a/headless/test/headless_js_bindings_browsertest.cc b/headless/test/headless_js_bindings_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0b14df251b96bea093e3718d2b8552a149475c7c
|
| --- /dev/null
|
| +++ b/headless/test/headless_js_bindings_browsertest.cc
|
| @@ -0,0 +1,149 @@
|
| +// 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 <memory>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/base64.h"
|
| +#include "base/json/json_reader.h"
|
| +#include "base/path_service.h"
|
| +#include "base/threading/thread_restrictions.h"
|
| +#include "content/public/test/browser_test.h"
|
| +#include "headless/grit/headless_browsertest_resources.h"
|
| +#include "headless/public/devtools/domains/runtime.h"
|
| +#include "headless/public/headless_browser.h"
|
| +#include "headless/public/headless_devtools_client.h"
|
| +#include "headless/public/headless_tab_socket.h"
|
| +#include "headless/public/headless_web_contents.h"
|
| +#include "headless/test/headless_browser_test.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| +
|
| +namespace headless {
|
| +
|
| +class HeadlessJsBindingsTest
|
| + : public HeadlessAsyncDevTooledBrowserTest,
|
| + public HeadlessTabSocket::Listener,
|
| + public HeadlessDevToolsClient::RawProtocolListener {
|
| + public:
|
| + void SetUp() override {
|
| + options()->mojo_service_names.insert("headless::TabSocket");
|
| + HeadlessAsyncDevTooledBrowserTest::SetUp();
|
| + }
|
| +
|
| + void SetUpOnMainThread() override {
|
| + base::ThreadRestrictions::SetIOAllowed(true);
|
| + base::FilePath pak_path;
|
| + ASSERT_TRUE(PathService::Get(base::DIR_MODULE, &pak_path));
|
| + pak_path = pak_path.AppendASCII("headless_browser_tests.pak");
|
| + ResourceBundle::GetSharedInstance().AddDataPackFromPath(
|
| + pak_path, ui::SCALE_FACTOR_NONE);
|
| + }
|
| +
|
| + void RunDevTooledTest() override {
|
| + headless_tab_socket_ = web_contents_->GetHeadlessTabSocket();
|
| + DCHECK(headless_tab_socket_);
|
| + headless_tab_socket_->SetListener(this);
|
| + devtools_client_->SetRawProtocolListener(this);
|
| + devtools_client_->GetRuntime()->Evaluate(
|
| + ResourceBundle::GetSharedInstance()
|
| + .GetRawDataResource(DEVTOOLS_BINDINGS_TEST)
|
| + .as_string(),
|
| + base::Bind(&HeadlessJsBindingsTest::OnEvaluateResult,
|
| + base::Unretained(this)));
|
| + RunJsBindingsTest();
|
| + }
|
| +
|
| + virtual void RunJsBindingsTest() = 0;
|
| + virtual std::string GetExpectedResult() = 0;
|
| +
|
| + void OnEvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) {
|
| + if (!result->HasExceptionDetails())
|
| + return;
|
| +
|
| + FinishAsynchronousTest();
|
| + FAIL() << result->GetExceptionDetails()->GetText();
|
| + }
|
| +
|
| + void OnMessageFromTab(const std::string& json_message) override {
|
| + std::unique_ptr<base::Value> message =
|
| + base::JSONReader::Read(json_message, base::JSON_PARSE_RFC);
|
| + const base::DictionaryValue* message_dict;
|
| + const base::DictionaryValue* params_dict;
|
| + std::string method;
|
| + int id;
|
| + if (!message || !message->GetAsDictionary(&message_dict) ||
|
| + !message_dict->GetString("method", &method) ||
|
| + !message_dict->GetDictionary("params", ¶ms_dict) ||
|
| + !message_dict->GetInteger("id", &id)) {
|
| + FinishAsynchronousTest();
|
| + FAIL() << "Badly formed message " << json_message;
|
| + return;
|
| + }
|
| +
|
| + if (method == "__Result") {
|
| + std::string result;
|
| + params_dict->GetString("result", &result);
|
| + EXPECT_EQ(GetExpectedResult(), result);
|
| + FinishAsynchronousTest();
|
| + return;
|
| + }
|
| +
|
| + devtools_client_->SendRawDevToolsMessage(json_message);
|
| + }
|
| +
|
| + HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override {
|
| + return HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD;
|
| + }
|
| +
|
| + bool OnProtocolMessage(const std::string& devtools_agent_host_id,
|
| + const std::string& json_message,
|
| + const base::DictionaryValue& parsed_message) override {
|
| + int id;
|
| + // If |parsed_message| contains an id we know this is a message reply.
|
| + if (parsed_message.GetInteger("id", &id)) {
|
| + // We are only interested in message replies (ones with an id) where the
|
| + // id is odd. The reason is HeadlessDevToolsClientImpl uses even/oddness
|
| + // to distinguish between commands send from the C++ bindings and those
|
| + // via HeadlessDevToolsClientImpl::SendRawDevToolsMessage.
|
| + if ((id % 2) == 0)
|
| + return false;
|
| + }
|
| +
|
| + headless_tab_socket_->SendMessageToTab(json_message);
|
| + return true;
|
| + }
|
| +
|
| + private:
|
| + HeadlessTabSocket* headless_tab_socket_;
|
| +};
|
| +
|
| +class SimpleCommandJsBindingsTest : public HeadlessJsBindingsTest {
|
| + public:
|
| + void RunJsBindingsTest() override {
|
| + devtools_client_->GetRuntime()->Evaluate(
|
| + "chromium.BindingsTest.evalOneAddOne()");
|
| + }
|
| +
|
| + std::string GetExpectedResult() override { return "2"; }
|
| +};
|
| +
|
| +HEADLESS_ASYNC_DEVTOOLED_TEST_F(SimpleCommandJsBindingsTest);
|
| +
|
| +class SimpleEventJsBindingsTest : public HeadlessJsBindingsTest {
|
| + public:
|
| + void RunJsBindingsTest() override {
|
| + devtools_client_->GetRuntime()->Evaluate(
|
| + "chromium.BindingsTest.listenForChildNodeCountUpdated()");
|
| + }
|
| +
|
| + std::string GetExpectedResult() override {
|
| + return "{\"nodeId\":4,\"childNodeCount\":1}";
|
| + }
|
| +};
|
| +
|
| +HEADLESS_ASYNC_DEVTOOLED_TEST_F(SimpleEventJsBindingsTest);
|
| +} // namespace headless
|
|
|