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

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: Added a comment 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 <fstream>
6 #include <iostream>
7 #include <memory>
8 #include "base/path_service.h"
9 #include "content/public/test/browser_test.h"
10 #include "headless/lib/embedder_test.mojom.h"
11 #include "headless/public/domains/page.h"
12 #include "headless/public/domains/runtime.h"
13 #include "headless/public/headless_browser.h"
14 #include "headless/public/headless_devtools_client.h"
15 #include "headless/public/headless_devtools_target.h"
16 #include "headless/public/headless_web_contents.h"
17 #include "headless/test/headless_browser_test.h"
18 #include "mojo/public/cpp/bindings/binding_set.h"
19 #include "mojo/public/cpp/bindings/interface_ptr_set.h"
20 #include "mojo/public/cpp/bindings/interface_request.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "url/gurl.h"
23
24 namespace headless {
25
26 namespace {
27 bool GetBuildDirectory(base::FilePath* result) {
28 if (!base::PathService::Get(base::DIR_EXE, result))
29 return false;
30
31 #if defined(OS_MACOSX)
Sami 2016/06/10 10:27:39 Let's leave this out until we actually support mac
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Done.
32 if (base::mac::AmIBundled()) {
33 // The bundled app executables (Chromium, TestShell, etc) live three
34 // levels down from the build directory, eg:
35 // Chromium.app/Contents/MacOS/Chromium
36 *result = result->DirName().DirName().DirName();
37 }
38 #endif
39 return true;
40 }
41 } // namespace
42
43 #define DEVTOOLS_CLIENT_TEST_F(TEST_FIXTURE_NAME) \
44 IN_PROC_BROWSER_TEST_F(TEST_FIXTURE_NAME, RunAsyncTest) { RunTest(); } \
45 class AsyncHeadlessBrowserTestNeedsSemicolon##TEST_FIXTURE_NAME {}
46
47 // A test fixture which attaches a devtools client before starting the test.
48 class EmbedderMojoTest : public HeadlessBrowserTest,
Sami 2016/06/10 10:27:39 Would it simplify things to subclass HeadlessAsync
alex clarke (OOO till 29th) 2016/06/11 20:51:50 This has got a lot simpler and I'm not sure that's
49 public HeadlessWebContents::Observer,
50 public page::Observer,
51 public embedder_test::TestEmbedderService {
52 public:
53 EmbedderMojoTest()
54 : web_contents_(nullptr),
55 devtools_client_(HeadlessDevToolsClient::Create()),
56 processed_page_ready_(false) {}
57 ~EmbedderMojoTest() override {}
58
59 // HeadlessWebContentsObserver implementation:
60 void DevToolsTargetReady() override {
Sami 2016/06/10 10:27:38 nit: Could you move these into chronological order
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Most of these methods have gone.
61 EXPECT_TRUE(web_contents_->GetDevToolsTarget());
62 web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
63
64 devtools_client_->GetPage()->AddObserver(this);
65 devtools_client_->GetPage()->Enable();
66
67 // Check if the page has reached the ready state.
68 devtools_client_->GetRuntime()->Evaluate(
69 "document.readyState",
70 base::Bind(&EmbedderMojoTest::OnReadyState, base::Unretained(this)));
71 }
72
73 virtual void RunMojoTest() = 0;
74
75 protected:
76 void RunTest() {
77 // The browser main thread does not have IO permissions so we need to ask
78 // another thread to load the mojo js bindings.
79 browser()->BrowserFileThread()->PostTask(
80 FROM_HERE,
81 base::Bind(&EmbedderMojoTest::LoadMojoJsBindingOnBrowserFileThread,
82 base::Unretained(this)));
83
84 RunAsynchronousTest();
85
86 web_contents_->GetDevToolsTarget()->DetachClient(devtools_client_.get());
87 web_contents_->RemoveObserver(this);
88 web_contents_->Close();
89 web_contents_ = nullptr;
90 }
91
92 void LoadMojoJsBindingOnBrowserFileThread() {
93 base::FilePath mojo_bindings_path;
94 ASSERT_TRUE(GetBuildDirectory(&mojo_bindings_path));
95 mojo_bindings_path = mojo_bindings_path.AppendASCII(
96 "gen/headless/lib/embedder_test.mojom.js");
97
98 ASSERT_TRUE(ReadFileToString(mojo_bindings_path, &mojo_js_binding_));
99
100 browser()->BrowserMainThread()->PostTask(
101 FROM_HERE,
102 base::Bind(&EmbedderMojoTest::CreateWebContentsOnBrowserMainThread,
103 base::Unretained(this)));
104 }
105
106 void CreateWebContentsOnBrowserMainThread() {
107 web_contents_ =
108 browser()
109 ->CreateWebContentsBuilder()
110 .AddEmbedderMojoService(
111 base::Bind(&EmbedderMojoTest::CreateTestEmbedderMojoService,
112 base::Unretained(this)),
113 mojo_js_binding_)
114 .Build();
115
116 web_contents_->AddObserver(this);
117 }
118
119 void CreateTestEmbedderMojoService(
120 mojo::InterfaceRequest<embedder_test::TestEmbedderService> request) {
121 test_embedder_mojo_bindings_.AddBinding(this, std::move(request));
122 }
123
124 void OnReadyState(std::unique_ptr<runtime::EvaluateResult> result) {
125 std::string ready_state;
126 if (result->GetResult()->GetValue()->GetAsString(&ready_state) &&
127 ready_state == "complete") {
128 OnPageReady();
129 return;
130 }
131 }
132
133 // page::Observer implementation:
134 void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
135 OnPageReady();
136 }
137
138 void OnPageReady() {
139 if (processed_page_ready_)
140 return;
141 processed_page_ready_ = true;
142 RunMojoTest();
143 }
144
145 HeadlessWebContents* web_contents_;
146 std::unique_ptr<HeadlessDevToolsClient> devtools_client_;
147
148 mojo::BindingSet<embedder_test::TestEmbedderService>
149 test_embedder_mojo_bindings_;
150 std::string mojo_js_binding_;
151 bool processed_page_ready_;
152 };
153
154 class EmbedderMojoBindingsTest : public EmbedderMojoTest {
155 public:
156 void RunMojoTest() override {
157 devtools_client_->GetRuntime()->Evaluate(
158 R"(
159 (function() {
160 // Note define() is the the mojo module dependency system.
161 define([
162 "headless/lib/embedder_test.mojom",
163 "mojo/public/js/core",
164 "mojo/public/js/router",
165 "content/public/renderer/frame_service_registry",
166 ], function(embedderMojom, mojoCore, routerModule,
167 serviceProvider) {
168 var testEmbedderService =
169 new embedderMojom.TestEmbedderService.proxyClass(
170 new routerModule.Router(
171 serviceProvider.connectToService(
172 embedderMojom.TestEmbedderService.name)));
173
174 // Send a message to the embedder!
175 testEmbedderService.returnTestResult("hello world");
176 });
177 })(); )",
178 base::Bind(&EmbedderMojoBindingsTest::OnEvalResult,
179 base::Unretained(this)));
180 }
181
182 void OnEvalResult(std::unique_ptr<runtime::EvaluateResult> result) {
183 EXPECT_FALSE(result->HasExceptionDetails())
184 << "JS exception: " << result->GetExceptionDetails()->GetText();
185 if (result->HasExceptionDetails()) {
186 FinishAsynchronousTest();
187 }
188 }
189
190 // embedder_test::TestEmbedderService:
191 void ReturnTestResult(const mojo::String& result) override {
192 EXPECT_EQ("hello world", result.get());
193 FinishAsynchronousTest();
194 }
195 };
196
197 DEVTOOLS_CLIENT_TEST_F(EmbedderMojoBindingsTest);
198
199 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698