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

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

Issue 2830753004: Pipe the devTools FrameId from blink into the browser for headless (Closed)
Patch Set: Rebased Created 3 years, 7 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 "base/bind.h"
6 #include "base/run_loop.h"
7 #include "content/public/test/browser_test.h"
8 #include "headless/lib/browser/headless_browser_context_impl.h"
9 #include "headless/lib/browser/headless_web_contents_impl.h"
10 #include "headless/public/devtools/domains/network.h"
11 #include "headless/public/devtools/domains/page.h"
12 #include "headless/public/headless_devtools_client.h"
13 #include "headless/public/util/expedited_dispatcher.h"
14 #include "headless/public/util/generic_url_request_job.h"
15 #include "headless/public/util/url_fetcher.h"
16 #include "headless/test/headless_browser_test.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request_job_factory.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
22
23 using testing::ContainerEq;
24
25 namespace headless {
26
27 namespace {
28 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
29 public:
30 explicit TestProtocolHandler(
31 scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner)
32 : test_delegate_(new TestDelegate(this)),
33 dispatcher_(new ExpeditedDispatcher(io_thread_task_runner)),
34 headless_browser_context_(nullptr) {}
35
36 ~TestProtocolHandler() override {}
37
38 void SetHeadlessBrowserContext(
39 HeadlessBrowserContext* headless_browser_context) {
40 headless_browser_context_ = headless_browser_context;
41 }
42
43 struct Response {
44 Response() {}
45 Response(const std::string& body, const std::string& mime_type)
46 : data("HTTP/1.1 200 OK\r\nContent-Type: " + mime_type + "\r\n\r\n" +
47 body) {}
48
49 std::string data;
50 };
51
52 void InsertResponse(const std::string& url, const Response& response) {
53 response_map_[url] = response;
54 }
55
56 const Response* GetResponse(const std::string& url) const {
57 std::map<std::string, Response>::const_iterator find_it =
58 response_map_.find(url);
59 if (find_it == response_map_.end())
60 return nullptr;
61 return &find_it->second;
62 }
63
64 class MockURLFetcher : public URLFetcher {
65 public:
66 explicit MockURLFetcher(const TestProtocolHandler* protocol_handler)
67 : protocol_handler_(protocol_handler) {}
68 ~MockURLFetcher() override {}
69
70 // URLFetcher implementation:
71 void StartFetch(const GURL& url,
72 const std::string& method,
73 const std::string& post_data,
74 const net::HttpRequestHeaders& request_headers,
75 ResultListener* result_listener) override {
76 EXPECT_EQ("GET", method);
77
78 const Response* response = protocol_handler_->GetResponse(url.spec());
79 if (!response)
80 result_listener->OnFetchStartError(net::ERR_FILE_NOT_FOUND);
81
82 result_listener->OnFetchCompleteExtractHeaders(
83 url, response->data.c_str(), response->data.size());
84 }
85
86 private:
87 const TestProtocolHandler* protocol_handler_;
88
89 DISALLOW_COPY_AND_ASSIGN(MockURLFetcher);
90 };
91
92 class TestDelegate : public GenericURLRequestJob::Delegate {
93 public:
94 explicit TestDelegate(TestProtocolHandler* protocol_handler)
95 : protocol_handler_(protocol_handler) {}
96
97 ~TestDelegate() override {}
98
99 // GenericURLRequestJob::Delegate implementation:
100 void OnPendingRequest(PendingRequest* pending_request) override {
101 const Request* request = pending_request->GetRequest();
102 std::string url = request->GetURLRequest()->url().spec();
103 int frame_tree_node_id = request->GetFrameTreeNodeId();
104 DCHECK_NE(frame_tree_node_id, -1);
105 protocol_handler_->url_to_frame_tree_node_id_[url] = frame_tree_node_id;
106 pending_request->AllowRequest();
107 }
108
109 void OnResourceLoadFailed(const Request* request,
110 net::Error error) override {}
111
112 void OnResourceLoadComplete(
113 const Request* request,
114 const GURL& final_url,
115 scoped_refptr<net::HttpResponseHeaders> response_headers,
116 const char* body,
117 size_t body_size) override {}
118
119 private:
120 TestProtocolHandler* protocol_handler_; // NOT OWNED
121 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;
122
123 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
124 };
125
126 // net::URLRequestJobFactory::ProtocolHandler implementation::
127 net::URLRequestJob* MaybeCreateJob(
128 net::URLRequest* request,
129 net::NetworkDelegate* network_delegate) const override {
130 return new GenericURLRequestJob(
131 request, network_delegate, dispatcher_.get(),
132 base::MakeUnique<MockURLFetcher>(this), test_delegate_.get(),
133 headless_browser_context_);
134 }
135
136 std::map<std::string, int> url_to_frame_tree_node_id_;
137
138 private:
139 std::unique_ptr<TestDelegate> test_delegate_;
140 std::unique_ptr<ExpeditedDispatcher> dispatcher_;
141 std::map<std::string, Response> response_map_;
142 HeadlessBrowserContext* headless_browser_context_;
143
144 DISALLOW_COPY_AND_ASSIGN(TestProtocolHandler);
145 };
146
147 const char* kIndexHtml = R"(
148 <html>
149 <head><link rel="stylesheet" type="text/css" href="style1.css"></head>
150 <body>
151 <div class="red">Main frame</div>
152 <iframe src="iframe1.html"></iframe>
153 <iframe src="iframe2.html"></iframe>
154 </body>
155 </html>)";
156
157 const char* kIFrame1 = R"(
158 <html>
159 <head><link rel="stylesheet" type="text/css" href="style2.css"></head>
160 <body>
161 <div class="green">IFrame 1</div>
162 </body>
163 </html>)";
164
165 const char* kIFrame2 = R"(
166 <html>
167 <head><link rel="stylesheet" type="text/css" href="style3.css"></head>
168 <body>
169 <div class="blue">IFrame 1</div>
170 </body>
171 </html>)";
172
173 const char* kStyle1Css = R"(
174 .red {
175 color: #f00
176 } )";
177
178 const char* kStyle2Css = R"(
179 .green {
180 color: #0f0
181 } )";
182
183 const char* kStyle3Css = R"(
184 .blue {
185 color: #00f
186 } )";
187
188 } // namespace
189
190 class FrameIdTest : public HeadlessAsyncDevTooledBrowserTest,
191 public network::Observer,
192 public page::Observer {
193 public:
194 void RunDevTooledTest() override {
195 http_handler_->SetHeadlessBrowserContext(browser_context_);
196
197 EXPECT_TRUE(embedded_test_server()->Start());
198 devtools_client_->GetNetwork()->AddObserver(this);
199 devtools_client_->GetNetwork()->Enable();
200 devtools_client_->GetPage()->AddObserver(this);
201
202 base::RunLoop run_loop;
203 devtools_client_->GetPage()->Enable(run_loop.QuitClosure());
204 base::MessageLoop::ScopedNestableTaskAllower nest_loop(
205 base::MessageLoop::current());
206 run_loop.Run();
207
208 devtools_client_->GetPage()->Navigate("http://foo.com/index.html");
209 }
210
211 ProtocolHandlerMap GetProtocolHandlers() override {
212 ProtocolHandlerMap protocol_handlers;
213 std::unique_ptr<TestProtocolHandler> http_handler(
214 new TestProtocolHandler(browser()->BrowserIOThread()));
215 http_handler_ = http_handler.get();
216 http_handler_->InsertResponse("http://foo.com/index.html",
217 {kIndexHtml, "text/html"});
218 http_handler_->InsertResponse("http://foo.com/iframe1.html",
219 {kIFrame1, "text/html"});
220 http_handler_->InsertResponse("http://foo.com/iframe2.html",
221 {kIFrame2, "text/html"});
222 http_handler_->InsertResponse("http://foo.com/style1.css",
223 {kStyle1Css, "text/css"});
224 http_handler_->InsertResponse("http://foo.com/style2.css",
225 {kStyle2Css, "text/css"});
226 http_handler_->InsertResponse("http://foo.com/style3.css",
227 {kStyle3Css, "text/css"});
228 protocol_handlers[url::kHttpScheme] = std::move(http_handler);
229 return protocol_handlers;
230 }
231
232 // network::Observer implementation:
233 void OnRequestWillBeSent(
234 const network::RequestWillBeSentParams& params) override {
235 url_to_frame_id_[params.GetRequest()->GetUrl()] = params.GetFrameId();
236 }
237
238 // page::Observer implementation:
239 void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
240 std::map<std::string, std::string> protocol_handler_url_to_frame_id_;
241 for (const auto& pair : http_handler_->url_to_frame_tree_node_id_) {
242 HeadlessWebContentsImpl* headless_web_contents_impl =
243 static_cast<HeadlessWebContentsImpl*>(web_contents_);
244 // TODO(alexclarke): This will probably break with OOPIF, fix this.
245 // See https://bugs.chromium.org/p/chromium/issues/detail?id=715924
246 protocol_handler_url_to_frame_id_[pair.first] =
247 headless_web_contents_impl
248 ->GetUntrustedDevToolsFrameIdForFrameTreeNodeId(
249 headless_web_contents_impl->GetMainFrameRenderProcessId(),
250 pair.second);
251 }
252
253 EXPECT_THAT(url_to_frame_id_, protocol_handler_url_to_frame_id_);
254 EXPECT_EQ(6u, url_to_frame_id_.size());
255 FinishAsynchronousTest();
256 }
257
258 private:
259 std::map<std::string, std::string> url_to_frame_id_;
260 TestProtocolHandler* http_handler_; // NOT OWNED
261 };
262
263 HEADLESS_ASYNC_DEVTOOLED_TEST_F(FrameIdTest);
264
265 } // namespace headless
OLDNEW
« no previous file with comments | « headless/lib/browser/headless_web_contents_impl.cc ('k') | headless/public/headless_web_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698