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

Side by Side Diff: headless/lib/embedder_mojo_browsertest.cc

Issue 2049363003: Adds support for headless chrome embedder mojo services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactored the JS for clarity Created 4 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 2016 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 "content/public/test/browser_test.h"
7 #include "headless/grit/headless_browsertest_resources.h"
8 #include "headless/lib/embedder_test.mojom.h"
9 #include "headless/public/domains/runtime.h"
10 #include "headless/public/headless_browser.h"
11 #include "headless/public/headless_devtools_client.h"
12 #include "headless/public/headless_devtools_target.h"
13 #include "headless/public/headless_web_contents.h"
14 #include "headless/test/headless_browser_test.h"
15 #include "mojo/public/cpp/bindings/binding_set.h"
16 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
17 #include "mojo/public/cpp/bindings/interface_request.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "url/gurl.h"
21
22 namespace headless {
23
24 #define DEVTOOLS_CLIENT_TEST_F(TEST_FIXTURE_NAME) \
25 IN_PROC_BROWSER_TEST_F(TEST_FIXTURE_NAME, RunAsyncTest) { RunTest(); } \
26 class AsyncHeadlessBrowserTestNeedsSemicolon##TEST_FIXTURE_NAME {}
27
28 // A test fixture which attaches a devtools client before starting the test.
29 class EmbedderMojoTest : public HeadlessBrowserTest,
30 public HeadlessWebContents::Observer,
31 public embedder_test::TestEmbedderService {
32 public:
33 EmbedderMojoTest()
34 : web_contents_(nullptr),
35 devtools_client_(HeadlessDevToolsClient::Create()) {}
36 ~EmbedderMojoTest() override {}
37
38 // HeadlessWebContentsObserver implementation:
39 void DevToolsTargetReady() override {
40 EXPECT_TRUE(web_contents_->GetDevToolsTarget());
41 web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
42
43 RunMojoTest();
44 }
45
46 virtual void RunMojoTest() = 0;
47
48 virtual GURL GetInitialUrl() const { return GURL("about:blank"); }
49
50 void OnEvalResult(std::unique_ptr<runtime::EvaluateResult> result) {
51 EXPECT_FALSE(result->HasExceptionDetails())
52 << "JS exception: " << result->GetExceptionDetails()->GetText();
53 if (result->HasExceptionDetails()) {
54 FinishAsynchronousTest();
55 }
56 }
57
58 protected:
59 void RunTest() {
60 std::string embedder_test_mojom_js =
61 ResourceBundle::GetSharedInstance()
62 .GetRawDataResource(IDR_HEADLESS_EMBEDDER_TEST_MOJOM_JS)
63 .as_string();
Sami 2016/06/20 16:58:16 Idle thought: normal headless embedders probably w
alex clarke (OOO till 29th) 2016/06/20 23:19:13 Right but the API doesn't mention them? :)
Sami 2016/06/21 10:22:26 Yep, and we should probably keep it that way.
64 web_contents_ =
65 browser()
66 ->CreateWebContentsBuilder()
67 .SetInitialURL(GURL(GetInitialUrl()))
68 .AddMojoService(base::Bind(&EmbedderMojoTest::CreateTestMojoService,
69 base::Unretained(this)))
70 .AddJsMojoBindings("headless/lib/embedder_test.mojom",
71 embedder_test_mojom_js)
72 .Build();
73
74 web_contents_->AddObserver(this);
75 RunAsynchronousTest();
76
77 web_contents_->GetDevToolsTarget()->DetachClient(devtools_client_.get());
78 web_contents_->RemoveObserver(this);
79 web_contents_->Close();
80 web_contents_ = nullptr;
81 }
82
83 void CreateTestMojoService(
84 mojo::InterfaceRequest<embedder_test::TestEmbedderService> request) {
85 test_embedder_mojo_bindings_.AddBinding(this, std::move(request));
86 }
87
88 HeadlessWebContents* web_contents_;
89 std::unique_ptr<HeadlessDevToolsClient> devtools_client_;
90
91 mojo::BindingSet<embedder_test::TestEmbedderService>
92 test_embedder_mojo_bindings_;
93 };
94
95 class EmbedderMojoBindingsTest : public EmbedderMojoTest {
96 public:
97 void RunMojoTest() override {
98 devtools_client_->GetRuntime()->Evaluate(
99 R"(
100 mojo.services.embedder_test.TestEmbedderService.then(function(service) {
101 service.returnTestResult("hello world");
102 }); )",
103 base::Bind(&EmbedderMojoTest::OnEvalResult, base::Unretained(this)));
104 }
105
106 // embedder_test::TestEmbedderService:
107 void ReturnTestResult(const mojo::String& result) override {
108 EXPECT_EQ("hello world", result.get());
109 FinishAsynchronousTest();
110 }
111 };
112
113 DEVTOOLS_CLIENT_TEST_F(EmbedderMojoBindingsTest);
114
115 class RejectNonExistantBindingsTest : public EmbedderMojoTest {
Sami 2016/06/20 16:58:16 typo: Nonexistent (couple other instances too)
alex clarke (OOO till 29th) 2016/06/20 23:19:13 Done.
116 public:
117 void RunMojoTest() override {
118 devtools_client_->GetRuntime()->Evaluate(
119 R"(
120 mojo.services.embedder_test.TestEmbedderService.then(function(service) {
121 mojo.services.nonExistant.MojoService.then(function() {
122 service.returnTestResult("Fail - promise not rejected");
123 }).catch(function() {
124 service.returnTestResult("Pass - promise rejected");
125 });
126 }); )",
127 base::Bind(&EmbedderMojoTest::OnEvalResult, base::Unretained(this)));
128 }
129
130 // embedder_test::TestEmbedderService:
131 void ReturnTestResult(const mojo::String& result) override {
132 EXPECT_EQ("Pass - promise rejected", result.get());
133 FinishAsynchronousTest();
134 }
135 };
136
137 DEVTOOLS_CLIENT_TEST_F(RejectNonExistantBindingsTest);
138
139 // Test bindings that occur after the onload event, which is after the browser
140 // has sent us the bindings.
141 class DelayedRejectNonExistantBindingsTest : public EmbedderMojoTest {
142 public:
143 void RunMojoTest() override {
144 devtools_client_->GetRuntime()->Evaluate(
145 R"(
146 // Make sure our test code runs after the onload event.
147 requestAnimationFrame(function() {
Sami 2016/06/20 16:58:16 rAF can be triggered before the onload. Maybe sche
alex clarke (OOO till 29th) 2016/06/20 23:19:13 Done.
148 mojo.services.embedder_test.TestEmbedderService.then(
149 function(service) {
150 mojo.services.nonExistant.MojoService.then(function() {
151 service.returnTestResult("Fail - promise not rejected");
152 }).catch(function() {
153 service.returnTestResult("Pass - promise rejected");
154 });
155 });
156 }); )",
157 base::Bind(&EmbedderMojoTest::OnEvalResult, base::Unretained(this)));
158 }
159
160 // embedder_test::TestEmbedderService:
161 void ReturnTestResult(const mojo::String& result) override {
162 EXPECT_EQ("Pass - promise rejected", result.get());
163 FinishAsynchronousTest();
164 }
165 };
166
167 DEVTOOLS_CLIENT_TEST_F(DelayedRejectNonExistantBindingsTest);
168
169 class HeadScriptEmbedderMojoBindingsTest : public EmbedderMojoTest {
170 public:
171 HeadScriptEmbedderMojoBindingsTest() {
172 EXPECT_TRUE(embedded_test_server()->Start());
173 }
174
175 void RunMojoTest() override {}
176
177 GURL GetInitialUrl() const override {
178 return embedded_test_server()->GetURL("/mojo_test.html");
179 }
180
181 // embedder_test::TestEmbedderService:
182 void ReturnTestResult(const mojo::String& result) override {
183 EXPECT_EQ("hello world", result.get());
184 FinishAsynchronousTest();
185 }
186 };
187
188 DEVTOOLS_CLIENT_TEST_F(HeadScriptEmbedderMojoBindingsTest);
189
190 class DefaultMojoStyleBindingsTest : public EmbedderMojoTest {
191 public:
192 void RunMojoTest() override {
193 devtools_client_->GetRuntime()->Evaluate(
194 R"(
195 // Note define() defines a module in the mojo module dependency
196 // system. While we don't expose our module, the callback below only
197 // fires after the requested modules have been loaded.
198 define([
199 "headless/lib/embedder_test.mojom",
200 "mojo/public/js/core",
201 "mojo/public/js/router",
202 "content/public/renderer/frame_service_registry",
203 ], function(embedderMojom, mojoCore, routerModule,
204 serviceProvider) {
205 var testEmbedderService =
206 new embedderMojom.TestEmbedderService.proxyClass(
207 new routerModule.Router(
208 serviceProvider.connectToService(
209 embedderMojom.TestEmbedderService.name)));
210
211 // Send a message to the embedder!
212 testEmbedderService.returnTestResult("hello world");
213 }); )",
214 base::Bind(&EmbedderMojoTest::OnEvalResult, base::Unretained(this)));
215 }
216
217 // embedder_test::TestEmbedderService:
218 void ReturnTestResult(const mojo::String& result) override {
219 EXPECT_EQ("hello world", result.get());
220 FinishAsynchronousTest();
221 }
222 };
223
224 DEVTOOLS_CLIENT_TEST_F(DefaultMojoStyleBindingsTest);
225
226 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698