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

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: Rebase Created 4 years, 4 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
« no previous file with comments | « headless/lib/browser/headless_web_contents_impl.cc ('k') | headless/lib/embedder_test.mojom » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/path_service.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/threading/thread_restrictions.h"
9 #include "content/public/test/browser_test.h"
10 #include "headless/grit/headless_browsertest_resources.h"
11 #include "headless/lib/embedder_test.mojom.h"
12 #include "headless/public/domains/network.h"
13 #include "headless/public/domains/page.h"
14 #include "headless/public/domains/runtime.h"
15 #include "headless/public/headless_browser.h"
16 #include "headless/public/headless_devtools_client.h"
17 #include "headless/public/headless_devtools_target.h"
18 #include "headless/public/headless_web_contents.h"
19 #include "headless/test/headless_browser_test.h"
20 #include "mojo/public/cpp/bindings/binding_set.h"
21 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
22 #include "mojo/public/cpp/bindings/interface_request.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "url/gurl.h"
26
27 namespace headless {
28
29 #define DEVTOOLS_CLIENT_TEST_F(TEST_FIXTURE_NAME) \
30 IN_PROC_BROWSER_TEST_F(TEST_FIXTURE_NAME, RunAsyncTest) { RunTest(); } \
31 class AsyncHeadlessBrowserTestNeedsSemicolon##TEST_FIXTURE_NAME {}
32
33 // A test fixture which attaches a devtools client and registers a mojo
34 // interface before starting the test.
35 class EmbedderMojoTest : public HeadlessBrowserTest,
36 public HeadlessWebContents::Observer,
37 public embedder_test::TestEmbedderService {
38 public:
39 enum HttpPolicy { DEFAULT, ENABLE_HTTP };
40
41 EmbedderMojoTest() : EmbedderMojoTest(HttpPolicy::DEFAULT) {}
42
43 explicit EmbedderMojoTest(HttpPolicy http_policy)
44 : web_contents_(nullptr),
45 devtools_client_(HeadlessDevToolsClient::Create()),
46 http_policy_(http_policy) {}
47
48 ~EmbedderMojoTest() override {}
49
50 void SetUpOnMainThread() override {
51 base::ThreadRestrictions::SetIOAllowed(true);
52 base::FilePath pak_path;
53 ASSERT_TRUE(PathService::Get(base::DIR_MODULE, &pak_path));
54 pak_path = pak_path.AppendASCII("headless_browser_tests.pak");
55 ResourceBundle::GetSharedInstance().AddDataPackFromPath(
56 pak_path, ui::SCALE_FACTOR_NONE);
57 }
58
59 // HeadlessWebContentsObserver implementation:
60 void DevToolsTargetReady() override {
61 EXPECT_TRUE(web_contents_->GetDevToolsTarget());
62 web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
63
64 RunMojoTest();
65 }
66
67 virtual void RunMojoTest() = 0;
68
69 virtual GURL GetInitialUrl() const { return GURL("about:blank"); }
70
71 void OnEvalResult(std::unique_ptr<runtime::EvaluateResult> result) {
72 EXPECT_FALSE(result->HasExceptionDetails())
73 << "JS exception: " << result->GetExceptionDetails()->GetText();
74 if (result->HasExceptionDetails()) {
75 FinishAsynchronousTest();
76 }
77 }
78
79 protected:
80 void RunTest() {
81 // Using a pak file is idiomatic chromium style, but most embedders probably
82 // wouln't load the javascript bindings file this way.
83 std::string embedder_test_mojom_js =
84 ResourceBundle::GetSharedInstance()
85 .GetRawDataResource(IDR_HEADLESS_EMBEDDER_TEST_MOJOM_JS)
86 .as_string();
87
88 if (http_policy_ == HttpPolicy::ENABLE_HTTP) {
89 browser_context_ =
90 browser()
91 ->CreateBrowserContextBuilder()
92 .AddJsMojoBindings("headless/lib/embedder_test.mojom",
93 embedder_test_mojom_js)
94 .EnableUnsafeNetworkAccessWithMojoBindings(true)
95 .Build();
96 } else {
97 browser_context_ =
98 browser()
99 ->CreateBrowserContextBuilder()
100 .AddJsMojoBindings("headless/lib/embedder_test.mojom",
101 embedder_test_mojom_js)
102 .Build();
103 }
104
105 web_contents_ =
106 browser()
107 ->CreateWebContentsBuilder()
108 .SetInitialURL(GURL(GetInitialUrl()))
109 .SetBrowserContext(browser_context_.get())
110 .AddMojoService(base::Bind(&EmbedderMojoTest::CreateTestMojoService,
111 base::Unretained(this)))
112 .Build();
113
114 web_contents_->AddObserver(this);
115 RunAsynchronousTest();
116
117 web_contents_->GetDevToolsTarget()->DetachClient(devtools_client_.get());
118 web_contents_->RemoveObserver(this);
119 web_contents_->Close();
120 web_contents_ = nullptr;
121
122 browser_context_.reset();
123 }
124
125 void CreateTestMojoService(
126 mojo::InterfaceRequest<embedder_test::TestEmbedderService> request) {
127 test_embedder_mojo_bindings_.AddBinding(this, std::move(request));
128 }
129
130 std::unique_ptr<HeadlessBrowserContext> browser_context_;
131 HeadlessWebContents* web_contents_;
132 std::unique_ptr<HeadlessDevToolsClient> devtools_client_;
133
134 mojo::BindingSet<embedder_test::TestEmbedderService>
135 test_embedder_mojo_bindings_;
136
137 HttpPolicy http_policy_;
138 };
139
140 class MojoBindingsTest : public EmbedderMojoTest {
141 public:
142 void RunMojoTest() override {
143 devtools_client_->GetRuntime()->Evaluate(
144 "// Note define() defines a module in the mojo module dependency \n"
145 "// system. While we don't expose our module, the callback below only\n"
146 "// fires after the requested modules have been loaded. \n"
147 "define([ \n"
148 " 'headless/lib/embedder_test.mojom', \n"
149 " 'mojo/public/js/core', \n"
150 " 'mojo/public/js/router', \n"
151 " 'content/public/renderer/frame_service_registry', \n"
152 " ], function(embedderMojom, mojoCore, routerModule, \n"
153 " serviceProvider) { \n"
154 " var testEmbedderService = \n"
155 " new embedderMojom.TestEmbedderService.proxyClass( \n"
156 " new routerModule.Router( \n"
157 " serviceProvider.connectToService( \n"
158 " embedderMojom.TestEmbedderService.name))); \n"
159 " \n"
160 " // Send a message to the embedder! \n"
161 " testEmbedderService.returnTestResult('hello world'); \n"
162 "});",
163 base::Bind(&EmbedderMojoTest::OnEvalResult, base::Unretained(this)));
164 }
165
166 // embedder_test::TestEmbedderService:
167 void ReturnTestResult(const std::string& result) override {
168 EXPECT_EQ("hello world", result);
169 FinishAsynchronousTest();
170 }
171 };
172
173 DEVTOOLS_CLIENT_TEST_F(MojoBindingsTest);
174
175 class MojoBindingsReinstalledAfterNavigation : public EmbedderMojoTest {
176 public:
177 MojoBindingsReinstalledAfterNavigation()
178 : EmbedderMojoTest(HttpPolicy::ENABLE_HTTP), seen_page_one_(false) {
179 EXPECT_TRUE(embedded_test_server()->Start());
180 }
181
182 void SetUpOnMainThread() override {
183 // We want to make sure bindings work across browser initiated cross-origin
184 // navigation, which is why we're setting up this fake tld.
185 HeadlessBrowser::Options::Builder builder;
186 builder.SetHostResolverRules(
187 base::StringPrintf("MAP not-an-actual-domain.tld 127.0.0.1:%d",
188 embedded_test_server()->host_port_pair().port()));
189 SetBrowserOptions(builder.Build());
190
191 EmbedderMojoTest::SetUpOnMainThread();
192 }
193
194 void RunMojoTest() override {}
195
196 GURL GetInitialUrl() const override {
197 return embedded_test_server()->GetURL("/page_one.html");
198 }
199
200 // embedder_test::TestEmbedderService:
201 void ReturnTestResult(const std::string& result) override {
202 if (result == "page one") {
203 seen_page_one_ = true;
204 devtools_client_->GetPage()->Navigate(
205 "http://not-an-actual-domain.tld/page_two.html");
206 } else {
207 EXPECT_TRUE(seen_page_one_);
208 EXPECT_EQ("page two", result);
209 FinishAsynchronousTest();
210 }
211 }
212
213 private:
214 bool seen_page_one_;
215 };
216
217 DEVTOOLS_CLIENT_TEST_F(MojoBindingsReinstalledAfterNavigation);
218
219 class HttpDisabledByDefaultWhenMojoBindingsUsed : public EmbedderMojoTest,
220 network::Observer,
221 page::Observer {
222 public:
223 HttpDisabledByDefaultWhenMojoBindingsUsed() {
224 EXPECT_TRUE(embedded_test_server()->Start());
225 }
226
227 void RunMojoTest() override {
228 devtools_client_->GetNetwork()->AddObserver(this);
229 devtools_client_->GetNetwork()->Enable();
230 }
231
232 GURL GetInitialUrl() const override {
233 return embedded_test_server()->GetURL("/page_one.html");
234 }
235
236 void ReturnTestResult(const std::string& result) override {
237 FinishAsynchronousTest();
238 FAIL() << "The HTTP page should not have been served and we should not have"
239 " recieved a mojo callback!";
240 }
241
242 void OnLoadingFailed(const network::LoadingFailedParams& params) override {
243 // The navigation should fail since HTTP requests are blackholed.
244 EXPECT_EQ(params.GetErrorText(), "net::ERR_FILE_NOT_FOUND");
245 FinishAsynchronousTest();
246 }
247 };
248
249 DEVTOOLS_CLIENT_TEST_F(HttpDisabledByDefaultWhenMojoBindingsUsed);
250
251 } // namespace headless
OLDNEW
« no previous file with comments | « headless/lib/browser/headless_web_contents_impl.cc ('k') | headless/lib/embedder_test.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698