Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: headless/test/headless_js_bindings_browsertest.cc

Issue 2902583002: Add some closureised JS bindings for DevTools for use by headless embedder (Closed)
Patch Set: Use goog.forwardDeclare where needed Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6 #include <string>
7 #include <vector>
8
9 #include "base/base64.h"
10 #include "base/json/json_reader.h"
11 #include "base/path_service.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "content/public/test/browser_test.h"
14 #include "headless/grit/headless_browsertest_resources.h"
15 #include "headless/public/devtools/domains/runtime.h"
16 #include "headless/public/headless_browser.h"
17 #include "headless/public/headless_devtools_client.h"
18 #include "headless/public/headless_tab_socket.h"
19 #include "headless/public/headless_web_contents.h"
20 #include "headless/test/headless_browser_test.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/base/resource/resource_bundle.h"
24
25 namespace headless {
26
27 class HeadlessJsBindingsTest
28 : public HeadlessAsyncDevTooledBrowserTest,
29 public HeadlessTabSocket::Listener,
30 public HeadlessDevToolsClient::RawProtocolListener {
31 public:
32 void SetUp() override {
33 options()->mojo_service_names.insert("headless::TabSocket");
34 HeadlessAsyncDevTooledBrowserTest::SetUp();
35 }
36
37 void SetUpOnMainThread() override {
38 base::ThreadRestrictions::SetIOAllowed(true);
39 base::FilePath pak_path;
40 ASSERT_TRUE(PathService::Get(base::DIR_MODULE, &pak_path));
41 pak_path = pak_path.AppendASCII("headless_browser_tests.pak");
42 ResourceBundle::GetSharedInstance().AddDataPackFromPath(
43 pak_path, ui::SCALE_FACTOR_NONE);
44 }
45
46 void RunDevTooledTest() override {
47 headless_tab_socket_ = web_contents_->GetHeadlessTabSocket();
48 DCHECK(headless_tab_socket_);
49 headless_tab_socket_->SetListener(this);
50 devtools_client_->SetRawProtocolListener(this);
51 devtools_client_->GetRuntime()->Evaluate(
52 ResourceBundle::GetSharedInstance()
53 .GetRawDataResource(DEVTOOLS_BINDINGS_TEST)
54 .as_string(),
55 base::Bind(&HeadlessJsBindingsTest::OnEvaluateResult,
56 base::Unretained(this)));
57 RunJsBindingsTest();
58 }
59
60 virtual void RunJsBindingsTest() = 0;
61 virtual std::string GetExpectedResult() = 0;
62
63 void OnEvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) {
64 if (!result->HasExceptionDetails())
65 return;
66
67 FinishAsynchronousTest();
68 FAIL() << result->GetExceptionDetails()->GetText();
69 }
70
71 void OnMessageFromTab(const std::string& json_message) override {
72 std::unique_ptr<base::Value> message =
73 base::JSONReader::Read(json_message, base::JSON_PARSE_RFC);
74 const base::DictionaryValue* message_dict;
75 const base::DictionaryValue* params_dict;
76 std::string method;
77 int id;
78 if (!message || !message->GetAsDictionary(&message_dict) ||
79 !message_dict->GetString("method", &method) ||
80 !message_dict->GetDictionary("params", &params_dict) ||
81 !message_dict->GetInteger("id", &id)) {
82 FinishAsynchronousTest();
83 FAIL() << "Badly formed message " << json_message;
84 return;
85 }
86
87 if (method == "__Result") {
88 std::string result;
89 params_dict->GetString("result", &result);
90 EXPECT_EQ(GetExpectedResult(), result);
91 FinishAsynchronousTest();
92 return;
93 }
94
95 devtools_client_->SendRawDevToolsMessage(json_message);
96 }
97
98 HeadlessWebContents::Builder::TabSocketType GetTabSocketType() override {
99 return HeadlessWebContents::Builder::TabSocketType::MAIN_WORLD;
100 }
101
102 bool OnProtocolMessage(const std::string& devtools_agent_host_id,
103 const std::string& json_message,
104 const base::DictionaryValue& parsed_message) override {
105 int id;
106 // If |parsed_message| contains an id we know this is a message reply.
107 if (parsed_message.GetInteger("id", &id)) {
108 // We are only interested in message replies (ones with an id) where the
109 // id is odd. The reason is HeadlessDevToolsClientImpl uses even/oddness
110 // to distinguish between commands send from the C++ bindings and those
111 // via HeadlessDevToolsClientImpl::SendRawDevToolsMessage.
112 if ((id % 2) == 0)
113 return false;
114 }
115
116 headless_tab_socket_->SendMessageToTab(json_message);
117 return true;
118 }
119
120 private:
121 HeadlessTabSocket* headless_tab_socket_;
122 };
123
124 class SimpleCommandJsBindingsTest : public HeadlessJsBindingsTest {
125 public:
126 void RunJsBindingsTest() override {
127 devtools_client_->GetRuntime()->Evaluate(
128 "chromium.BindingsTest.evalOneAddOne()");
129 }
130
131 std::string GetExpectedResult() override { return "2"; }
132 };
133
134 HEADLESS_ASYNC_DEVTOOLED_TEST_F(SimpleCommandJsBindingsTest);
135
136 class SimpleEventJsBindingsTest : public HeadlessJsBindingsTest {
137 public:
138 void RunJsBindingsTest() override {
139 devtools_client_->GetRuntime()->Evaluate(
140 "chromium.BindingsTest.listenForChildNodeCountUpdated()");
141 }
142
143 std::string GetExpectedResult() override {
144 return "{\"nodeId\":4,\"childNodeCount\":1}";
145 }
146 };
147
148 HEADLESS_ASYNC_DEVTOOLED_TEST_F(SimpleEventJsBindingsTest);
149 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698