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

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

Issue 2092773002: headless: Allow per-context protocol handlers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed comments 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
« no previous file with comments | « headless/lib/headless_browser_browsertest.cc ('k') | headless/public/headless_browser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 6
7 #include "base/memory/ptr_util.h" 7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "content/public/test/browser_test.h" 9 #include "content/public/test/browser_test.h"
10 #include "headless/public/domains/page.h"
11 #include "headless/public/domains/runtime.h" 10 #include "headless/public/domains/runtime.h"
12 #include "headless/public/domains/types.h"
13 #include "headless/public/headless_browser.h" 11 #include "headless/public/headless_browser.h"
14 #include "headless/public/headless_browser_context.h" 12 #include "headless/public/headless_browser_context.h"
15 #include "headless/public/headless_devtools_client.h" 13 #include "headless/public/headless_devtools_client.h"
16 #include "headless/public/headless_devtools_target.h" 14 #include "headless/public/headless_devtools_target.h"
17 #include "headless/public/headless_web_contents.h" 15 #include "headless/public/headless_web_contents.h"
18 #include "headless/test/headless_browser_test.h" 16 #include "headless/test/headless_browser_test.h"
17 #include "headless/test/test_protocol_handler.h"
19 #include "net/base/io_buffer.h" 18 #include "net/base/io_buffer.h"
20 #include "net/http/http_response_headers.h" 19 #include "net/http/http_response_headers.h"
21 #include "net/test/spawned_test_server/spawned_test_server.h" 20 #include "net/test/spawned_test_server/spawned_test_server.h"
22 #include "net/url_request/url_request_job.h" 21 #include "net/url_request/url_request_job.h"
23 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
24 #include "ui/gfx/geometry/size.h" 23 #include "ui/gfx/geometry/size.h"
25 24
26 namespace headless { 25 namespace headless {
27 namespace { 26 namespace {
28
29 class TestURLRequestJob : public net::URLRequestJob {
30 public:
31 TestURLRequestJob(net::URLRequest* request,
32 net::NetworkDelegate* network_delegate,
33 const std::string& body);
34 ~TestURLRequestJob() override {}
35
36 // net::URLRequestJob implementation:
37 void Start() override;
38 void GetResponseInfo(net::HttpResponseInfo* info) override;
39 int ReadRawData(net::IOBuffer* buf, int buf_size) override;
40
41 private:
42 scoped_refptr<net::StringIOBuffer> body_;
43 scoped_refptr<net::DrainableIOBuffer> src_buf_;
44
45 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJob);
46 };
47
48 TestURLRequestJob::TestURLRequestJob(net::URLRequest* request,
49 net::NetworkDelegate* network_delegate,
50 const std::string& body)
51 : net::URLRequestJob(request, network_delegate),
52 body_(new net::StringIOBuffer(body)),
53 src_buf_(new net::DrainableIOBuffer(body_.get(), body_->size())) {}
54
55 void TestURLRequestJob::Start() {
56 NotifyHeadersComplete();
57 }
58
59 void TestURLRequestJob::GetResponseInfo(net::HttpResponseInfo* info) {
60 info->headers =
61 new net::HttpResponseHeaders("Content-Type: text/html\r\n\r\n");
62 }
63
64 int TestURLRequestJob::ReadRawData(net::IOBuffer* buf, int buf_size) {
65 scoped_refptr<net::DrainableIOBuffer> dest_buf(
66 new net::DrainableIOBuffer(buf, buf_size));
67 while (src_buf_->BytesRemaining() > 0 && dest_buf->BytesRemaining() > 0) {
68 *dest_buf->data() = *src_buf_->data();
69 src_buf_->DidConsume(1);
70 dest_buf->DidConsume(1);
71 }
72 return dest_buf->BytesConsumed();
73 }
74
75 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
76 public:
77 TestProtocolHandler(const std::string& body);
78 ~TestProtocolHandler() override {}
79
80 net::URLRequestJob* MaybeCreateJob(
81 net::URLRequest* request,
82 net::NetworkDelegate* network_delegate) const override;
83
84 private:
85 std::string body_;
86
87 DISALLOW_COPY_AND_ASSIGN(TestProtocolHandler);
88 };
89
90 TestProtocolHandler::TestProtocolHandler(const std::string& body)
91 : body_(body) {}
92
93 net::URLRequestJob* TestProtocolHandler::MaybeCreateJob(
94 net::URLRequest* request,
95 net::NetworkDelegate* network_delegate) const {
96 return new TestURLRequestJob(request, network_delegate, body_);
97 }
98
99 } // namespace
100
101 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyWebContents) {
102 HeadlessWebContents* web_contents =
103 browser()->CreateWebContentsBuilder().Build();
104 EXPECT_TRUE(web_contents);
105
106 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size());
107 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]);
108 // TODO(skyostil): Verify viewport dimensions once we can.
109 web_contents->Close();
110
111 EXPECT_TRUE(browser()->GetAllWebContents().empty());
112 }
113
114 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateWithBadURL) {
115 GURL bad_url("not_valid");
116 HeadlessWebContents* web_contents =
117 browser()->CreateWebContentsBuilder().SetInitialURL(bad_url).Build();
118 EXPECT_FALSE(web_contents);
119 EXPECT_TRUE(browser()->GetAllWebContents().empty());
120 }
121
122 class HeadlessBrowserTestWithProxy : public HeadlessBrowserTest {
123 public:
124 HeadlessBrowserTestWithProxy()
125 : proxy_server_(net::SpawnedTestServer::TYPE_HTTP,
126 net::SpawnedTestServer::kLocalhost,
127 base::FilePath(FILE_PATH_LITERAL("headless/test/data"))) {
128 }
129
130 void SetUp() override {
131 ASSERT_TRUE(proxy_server_.Start());
132 HeadlessBrowserTest::SetUp();
133 }
134
135 void TearDown() override {
136 proxy_server_.Stop();
137 HeadlessBrowserTest::TearDown();
138 }
139
140 net::SpawnedTestServer* proxy_server() { return &proxy_server_; }
141
142 private:
143 net::SpawnedTestServer proxy_server_;
144 };
145
146 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTestWithProxy, SetProxyServer) {
147 HeadlessBrowser::Options::Builder builder;
148 builder.SetProxyServer(proxy_server()->host_port_pair());
149 SetBrowserOptions(builder.Build());
150
151 // Load a page which doesn't actually exist, but for which the our proxy
152 // returns valid content anyway.
153 //
154 // TODO(altimin): Currently this construction does not serve hello.html
155 // from headless/test/data as expected. We should fix this.
156 HeadlessWebContents* web_contents =
157 browser()
158 ->CreateWebContentsBuilder()
159 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
160 .Build();
161 EXPECT_TRUE(WaitForLoad(web_contents));
162 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size());
163 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]);
164 web_contents->Close();
165 EXPECT_TRUE(browser()->GetAllWebContents().empty());
166 }
167
168 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, SetHostResolverRules) {
169 EXPECT_TRUE(embedded_test_server()->Start());
170 HeadlessBrowser::Options::Builder builder;
171 builder.SetHostResolverRules(
172 base::StringPrintf("MAP not-an-actual-domain.tld 127.0.0.1:%d",
173 embedded_test_server()->host_port_pair().port()));
174 SetBrowserOptions(builder.Build());
175
176 // Load a page which doesn't actually exist, but which is turned into a valid
177 // address by our host resolver rules.
178 HeadlessWebContents* web_contents =
179 browser()
180 ->CreateWebContentsBuilder()
181 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
182 .Build();
183 EXPECT_TRUE(WaitForLoad(web_contents));
184 }
185
186 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpProtocolHandler) {
187 const std::string kResponseBody = "<p>HTTP response body</p>";
188 ProtocolHandlerMap protocol_handlers;
189 protocol_handlers[url::kHttpScheme] =
190 base::WrapUnique(new TestProtocolHandler(kResponseBody));
191
192 HeadlessBrowser::Options::Builder builder;
193 builder.SetProtocolHandlers(std::move(protocol_handlers));
194 SetBrowserOptions(builder.Build());
195
196 // Load a page which doesn't actually exist, but which is fetched by our
197 // custom protocol handler.
198 HeadlessWebContents* web_contents =
199 browser()
200 ->CreateWebContentsBuilder()
201 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
202 .Build();
203 EXPECT_TRUE(WaitForLoad(web_contents));
204
205 std::string inner_html;
206 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
207 ->GetResult()
208 ->GetValue()
209 ->GetAsString(&inner_html));
210 EXPECT_EQ(kResponseBody, inner_html);
211 }
212
213 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpsProtocolHandler) {
214 const std::string kResponseBody = "<p>HTTPS response body</p>";
215 ProtocolHandlerMap protocol_handlers;
216 protocol_handlers[url::kHttpsScheme] =
217 base::WrapUnique(new TestProtocolHandler(kResponseBody));
218
219 HeadlessBrowser::Options::Builder builder;
220 builder.SetProtocolHandlers(std::move(protocol_handlers));
221 SetBrowserOptions(builder.Build());
222
223 // Load a page which doesn't actually exist, but which is fetched by our
224 // custom protocol handler.
225 HeadlessWebContents* web_contents =
226 browser()
227 ->CreateWebContentsBuilder()
228 .SetInitialURL(GURL("https://not-an-actual-domain.tld/hello.html"))
229 .Build();
230 EXPECT_TRUE(WaitForLoad(web_contents));
231
232 std::string inner_html;
233 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
234 ->GetResult()
235 ->GetValue()
236 ->GetAsString(&inner_html));
237 EXPECT_EQ(kResponseBody, inner_html);
238 }
239
240 namespace {
241 const char kMainPageCookie[] = "mood=quizzical"; 27 const char kMainPageCookie[] = "mood=quizzical";
242 const char kIsolatedPageCookie[] = "mood=quixotic"; 28 const char kIsolatedPageCookie[] = "mood=quixotic";
243 } // namespace 29 } // namespace
244 30
245 // This test creates two tabs pointing to the same security origin in two 31 // This test creates two tabs pointing to the same security origin in two
246 // different browser contexts and checks that they are isolated by creating two 32 // different browser contexts and checks that they are isolated by creating two
247 // cookies with the same name in both tabs. The steps are: 33 // cookies with the same name in both tabs. The steps are:
248 // 34 //
249 // 1. Wait for tab #1 to become ready for DevTools. 35 // 1. Wait for tab #1 to become ready for DevTools.
250 // 2. Create tab #2 and wait for it to become ready for DevTools. 36 // 2. Create tab #2 and wait for it to become ready for DevTools.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 149
364 private: 150 private:
365 std::unique_ptr<HeadlessBrowserContext> browser_context_; 151 std::unique_ptr<HeadlessBrowserContext> browser_context_;
366 HeadlessWebContents* web_contents2_; 152 HeadlessWebContents* web_contents2_;
367 std::unique_ptr<HeadlessDevToolsClient> devtools_client2_; 153 std::unique_ptr<HeadlessDevToolsClient> devtools_client2_;
368 std::unique_ptr<LoadObserver> load_observer_; 154 std::unique_ptr<LoadObserver> load_observer_;
369 }; 155 };
370 156
371 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessBrowserContextIsolationTest); 157 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessBrowserContextIsolationTest);
372 158
159 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ContextProtocolHandler) {
160 const std::string kResponseBody = "<p>HTTP response body</p>";
161 ProtocolHandlerMap protocol_handlers;
162 protocol_handlers[url::kHttpScheme] =
163 base::WrapUnique(new TestProtocolHandler(kResponseBody));
164
165 // Load a page which doesn't actually exist, but which is fetched by our
166 // custom protocol handler.
167 std::unique_ptr<HeadlessBrowserContext> browser_context =
168 browser()
169 ->CreateBrowserContextBuilder()
170 .SetProtocolHandlers(std::move(protocol_handlers))
171 .Build();
172 HeadlessWebContents* web_contents =
173 browser()
174 ->CreateWebContentsBuilder()
175 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
176 .SetBrowserContext(browser_context.get())
177 .Build();
178 EXPECT_TRUE(WaitForLoad(web_contents));
179
180 std::string inner_html;
181 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
182 ->GetResult()
183 ->GetValue()
184 ->GetAsString(&inner_html));
185 EXPECT_EQ(kResponseBody, inner_html);
186 web_contents->Close();
187
188 // Loading the same non-existent page using a tab with the default context
189 // should not work since the protocol handler only exists on the custom
190 // context.
191 web_contents =
192 browser()
193 ->CreateWebContentsBuilder()
194 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html"))
195 .Build();
196 EXPECT_TRUE(WaitForLoad(web_contents));
197 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML")
198 ->GetResult()
199 ->GetValue()
200 ->GetAsString(&inner_html));
201 EXPECT_EQ("", inner_html);
202 web_contents->Close();
203 }
204
373 } // namespace headless 205 } // namespace headless
OLDNEW
« no previous file with comments | « headless/lib/headless_browser_browsertest.cc ('k') | headless/public/headless_browser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698