OLD | NEW |
---|---|
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/types.h" | 12 #include "headless/public/domains/types.h" |
11 #include "headless/public/headless_browser.h" | 13 #include "headless/public/headless_browser.h" |
14 #include "headless/public/headless_browser_context.h" | |
15 #include "headless/public/headless_devtools_client.h" | |
16 #include "headless/public/headless_devtools_target.h" | |
12 #include "headless/public/headless_web_contents.h" | 17 #include "headless/public/headless_web_contents.h" |
13 #include "headless/test/headless_browser_test.h" | 18 #include "headless/test/headless_browser_test.h" |
14 #include "net/base/io_buffer.h" | 19 #include "net/base/io_buffer.h" |
15 #include "net/http/http_response_headers.h" | 20 #include "net/http/http_response_headers.h" |
16 #include "net/test/spawned_test_server/spawned_test_server.h" | 21 #include "net/test/spawned_test_server/spawned_test_server.h" |
17 #include "net/url_request/url_request_job.h" | 22 #include "net/url_request/url_request_job.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
19 #include "ui/gfx/geometry/size.h" | 24 #include "ui/gfx/geometry/size.h" |
20 | 25 |
21 namespace headless { | 26 namespace headless { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 net::URLRequestJob* TestProtocolHandler::MaybeCreateJob( | 93 net::URLRequestJob* TestProtocolHandler::MaybeCreateJob( |
89 net::URLRequest* request, | 94 net::URLRequest* request, |
90 net::NetworkDelegate* network_delegate) const { | 95 net::NetworkDelegate* network_delegate) const { |
91 return new TestURLRequestJob(request, network_delegate, body_); | 96 return new TestURLRequestJob(request, network_delegate, body_); |
92 } | 97 } |
93 | 98 |
94 } // namespace | 99 } // namespace |
95 | 100 |
96 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyWebContents) { | 101 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyWebContents) { |
97 HeadlessWebContents* web_contents = | 102 HeadlessWebContents* web_contents = |
98 browser()->CreateWebContents(GURL("about:blank"), gfx::Size(800, 600)); | 103 browser()->CreateWebContentsBuilder().Build(); |
99 EXPECT_TRUE(web_contents); | 104 EXPECT_TRUE(web_contents); |
100 | 105 |
101 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size()); | 106 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size()); |
102 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]); | 107 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]); |
103 // TODO(skyostil): Verify viewport dimensions once we can. | 108 // TODO(skyostil): Verify viewport dimensions once we can. |
104 web_contents->Close(); | 109 web_contents->Close(); |
105 | 110 |
106 EXPECT_TRUE(browser()->GetAllWebContents().empty()); | 111 EXPECT_TRUE(browser()->GetAllWebContents().empty()); |
107 } | 112 } |
108 | 113 |
109 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateWithBadURL) { | 114 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateWithBadURL) { |
110 GURL bad_url("not_valid"); | 115 GURL bad_url("not_valid"); |
111 HeadlessWebContents* web_contents = | 116 HeadlessWebContents* web_contents = |
112 browser()->CreateWebContents(bad_url, gfx::Size(800, 600)); | 117 browser()->CreateWebContentsBuilder().SetInitialURL(bad_url).Build(); |
113 EXPECT_FALSE(web_contents); | 118 EXPECT_FALSE(web_contents); |
114 EXPECT_TRUE(browser()->GetAllWebContents().empty()); | 119 EXPECT_TRUE(browser()->GetAllWebContents().empty()); |
115 } | 120 } |
116 | 121 |
117 class HeadlessBrowserTestWithProxy : public HeadlessBrowserTest { | 122 class HeadlessBrowserTestWithProxy : public HeadlessBrowserTest { |
118 public: | 123 public: |
119 HeadlessBrowserTestWithProxy() | 124 HeadlessBrowserTestWithProxy() |
120 : proxy_server_(net::SpawnedTestServer::TYPE_HTTP, | 125 : proxy_server_(net::SpawnedTestServer::TYPE_HTTP, |
121 net::SpawnedTestServer::kLocalhost, | 126 net::SpawnedTestServer::kLocalhost, |
122 base::FilePath(FILE_PATH_LITERAL("headless/test/data"))) { | 127 base::FilePath(FILE_PATH_LITERAL("headless/test/data"))) { |
(...skipping 18 matching lines...) Expand all Loading... | |
141 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTestWithProxy, SetProxyServer) { | 146 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTestWithProxy, SetProxyServer) { |
142 HeadlessBrowser::Options::Builder builder; | 147 HeadlessBrowser::Options::Builder builder; |
143 builder.SetProxyServer(proxy_server()->host_port_pair()); | 148 builder.SetProxyServer(proxy_server()->host_port_pair()); |
144 SetBrowserOptions(builder.Build()); | 149 SetBrowserOptions(builder.Build()); |
145 | 150 |
146 // Load a page which doesn't actually exist, but for which the our proxy | 151 // Load a page which doesn't actually exist, but for which the our proxy |
147 // returns valid content anyway. | 152 // returns valid content anyway. |
148 // | 153 // |
149 // TODO(altimin): Currently this construction does not serve hello.html | 154 // TODO(altimin): Currently this construction does not serve hello.html |
150 // from headless/test/data as expected. We should fix this. | 155 // from headless/test/data as expected. We should fix this. |
151 HeadlessWebContents* web_contents = browser()->CreateWebContents( | 156 HeadlessWebContents* web_contents = |
152 GURL("http://not-an-actual-domain.tld/hello.html"), gfx::Size(800, 600)); | 157 browser() |
158 ->CreateWebContentsBuilder() | |
159 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html")) | |
160 .Build(); | |
153 EXPECT_TRUE(WaitForLoad(web_contents)); | 161 EXPECT_TRUE(WaitForLoad(web_contents)); |
154 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size()); | 162 EXPECT_EQ(static_cast<size_t>(1), browser()->GetAllWebContents().size()); |
155 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]); | 163 EXPECT_EQ(web_contents, browser()->GetAllWebContents()[0]); |
156 web_contents->Close(); | 164 web_contents->Close(); |
157 EXPECT_TRUE(browser()->GetAllWebContents().empty()); | 165 EXPECT_TRUE(browser()->GetAllWebContents().empty()); |
158 } | 166 } |
159 | 167 |
160 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, SetHostResolverRules) { | 168 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, SetHostResolverRules) { |
161 EXPECT_TRUE(embedded_test_server()->Start()); | 169 EXPECT_TRUE(embedded_test_server()->Start()); |
162 HeadlessBrowser::Options::Builder builder; | 170 HeadlessBrowser::Options::Builder builder; |
163 builder.SetHostResolverRules( | 171 builder.SetHostResolverRules( |
164 base::StringPrintf("MAP not-an-actual-domain.tld 127.0.0.1:%d", | 172 base::StringPrintf("MAP not-an-actual-domain.tld 127.0.0.1:%d", |
165 embedded_test_server()->host_port_pair().port())); | 173 embedded_test_server()->host_port_pair().port())); |
166 SetBrowserOptions(builder.Build()); | 174 SetBrowserOptions(builder.Build()); |
167 | 175 |
168 // Load a page which doesn't actually exist, but which is turned into a valid | 176 // Load a page which doesn't actually exist, but which is turned into a valid |
169 // address by our host resolver rules. | 177 // address by our host resolver rules. |
170 HeadlessWebContents* web_contents = browser()->CreateWebContents( | 178 HeadlessWebContents* web_contents = |
171 GURL("http://not-an-actual-domain.tld/hello.html"), gfx::Size(800, 600)); | 179 browser() |
180 ->CreateWebContentsBuilder() | |
181 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html")) | |
182 .Build(); | |
172 EXPECT_TRUE(WaitForLoad(web_contents)); | 183 EXPECT_TRUE(WaitForLoad(web_contents)); |
173 } | 184 } |
174 | 185 |
175 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpProtocolHandler) { | 186 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpProtocolHandler) { |
176 const std::string kResponseBody = "<p>HTTP response body</p>"; | 187 const std::string kResponseBody = "<p>HTTP response body</p>"; |
177 ProtocolHandlerMap protocol_handlers; | 188 ProtocolHandlerMap protocol_handlers; |
178 protocol_handlers[url::kHttpScheme] = | 189 protocol_handlers[url::kHttpScheme] = |
179 base::WrapUnique(new TestProtocolHandler(kResponseBody)); | 190 base::WrapUnique(new TestProtocolHandler(kResponseBody)); |
180 | 191 |
181 HeadlessBrowser::Options::Builder builder; | 192 HeadlessBrowser::Options::Builder builder; |
182 builder.SetProtocolHandlers(std::move(protocol_handlers)); | 193 builder.SetProtocolHandlers(std::move(protocol_handlers)); |
183 SetBrowserOptions(builder.Build()); | 194 SetBrowserOptions(builder.Build()); |
184 | 195 |
185 // Load a page which doesn't actually exist, but which is fetched by our | 196 // Load a page which doesn't actually exist, but which is fetched by our |
186 // custom protocol handler. | 197 // custom protocol handler. |
187 HeadlessWebContents* web_contents = browser()->CreateWebContents( | 198 HeadlessWebContents* web_contents = |
188 GURL("http://not-an-actual-domain.tld/hello.html"), gfx::Size(800, 600)); | 199 browser() |
200 ->CreateWebContentsBuilder() | |
201 .SetInitialURL(GURL("http://not-an-actual-domain.tld/hello.html")) | |
202 .Build(); | |
189 EXPECT_TRUE(WaitForLoad(web_contents)); | 203 EXPECT_TRUE(WaitForLoad(web_contents)); |
190 | 204 |
191 std::string inner_html; | 205 std::string inner_html; |
192 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML") | 206 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML") |
193 ->GetResult() | 207 ->GetResult() |
194 ->GetValue() | 208 ->GetValue() |
195 ->GetAsString(&inner_html)); | 209 ->GetAsString(&inner_html)); |
196 EXPECT_EQ(kResponseBody, inner_html); | 210 EXPECT_EQ(kResponseBody, inner_html); |
197 } | 211 } |
198 | 212 |
199 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpsProtocolHandler) { | 213 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, HttpsProtocolHandler) { |
200 const std::string kResponseBody = "<p>HTTPS response body</p>"; | 214 const std::string kResponseBody = "<p>HTTPS response body</p>"; |
201 ProtocolHandlerMap protocol_handlers; | 215 ProtocolHandlerMap protocol_handlers; |
202 protocol_handlers[url::kHttpsScheme] = | 216 protocol_handlers[url::kHttpsScheme] = |
203 base::WrapUnique(new TestProtocolHandler(kResponseBody)); | 217 base::WrapUnique(new TestProtocolHandler(kResponseBody)); |
204 | 218 |
205 HeadlessBrowser::Options::Builder builder; | 219 HeadlessBrowser::Options::Builder builder; |
206 builder.SetProtocolHandlers(std::move(protocol_handlers)); | 220 builder.SetProtocolHandlers(std::move(protocol_handlers)); |
207 SetBrowserOptions(builder.Build()); | 221 SetBrowserOptions(builder.Build()); |
208 | 222 |
209 // Load a page which doesn't actually exist, but which is fetched by our | 223 // Load a page which doesn't actually exist, but which is fetched by our |
210 // custom protocol handler. | 224 // custom protocol handler. |
211 HeadlessWebContents* web_contents = browser()->CreateWebContents( | 225 HeadlessWebContents* web_contents = |
212 GURL("https://not-an-actual-domain.tld/hello.html"), gfx::Size(800, 600)); | 226 browser() |
227 ->CreateWebContentsBuilder() | |
228 .SetInitialURL(GURL("https://not-an-actual-domain.tld/hello.html")) | |
229 .Build(); | |
213 EXPECT_TRUE(WaitForLoad(web_contents)); | 230 EXPECT_TRUE(WaitForLoad(web_contents)); |
214 | 231 |
215 std::string inner_html; | 232 std::string inner_html; |
216 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML") | 233 EXPECT_TRUE(EvaluateScript(web_contents, "document.body.innerHTML") |
217 ->GetResult() | 234 ->GetResult() |
218 ->GetValue() | 235 ->GetValue() |
219 ->GetAsString(&inner_html)); | 236 ->GetAsString(&inner_html)); |
220 EXPECT_EQ(kResponseBody, inner_html); | 237 EXPECT_EQ(kResponseBody, inner_html); |
221 } | 238 } |
222 | 239 |
240 namespace { | |
241 const char kMainPageCookie[] = "mood=quizzical"; | |
242 const char kIsolatedPageCookie[] = "mood=quixotic"; | |
243 } // namespace | |
244 | |
245 // 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 | |
247 // cookies with the same name in both tabs. The steps are: | |
248 // | |
249 // 1. Wait for tab #1 to become ready for DevTools. | |
250 // 2. Create tab #2 and wait for it to become ready for DevTools. | |
251 // 3. Navigate tab #1 to the test page and wait for it to finish loading. | |
252 // 4. Navigate tab #2 to the test page and wait for it to finish loading. | |
253 // 5. Set a cookie in tab #1. | |
254 // 6. Set the same cookie in tab #2 to a different value. | |
255 // 7. Read the cookie in tab #1 and check that it has the first value. | |
256 // 8. Read the cookie in tab #2 and check that it has the second value. | |
257 // | |
258 // If the tabs aren't properly isolated, step 7 will fail. | |
259 class HeadlessBrowserContextIsolationTest | |
260 : public HeadlessAsyncDevTooledBrowserTest { | |
261 public: | |
262 HeadlessBrowserContextIsolationTest() | |
263 : isolated_web_contents_(nullptr), | |
264 isolated_devtools_client_(HeadlessDevToolsClient::Create()) { | |
alex clarke (OOO till 29th)
2016/06/09 09:15:08
Can we call these web_contents2_ & devtools_client
Sami
2016/06/09 11:14:39
Agreed, that matches the description above too.
| |
265 EXPECT_TRUE(embedded_test_server()->Start()); | |
266 } | |
267 | |
268 // HeadlessWebContentsObserver implementation: | |
269 void DevToolsTargetReady() override { | |
270 if (!isolated_web_contents_) { | |
271 browser_context_ = browser()->CreateBrowserContextBuilder().Build(); | |
272 isolated_web_contents_ = browser() | |
273 ->CreateWebContentsBuilder() | |
274 .SetBrowserContext(browser_context_.get()) | |
275 .Build(); | |
276 isolated_web_contents_->AddObserver(this); | |
277 return; | |
278 } | |
279 | |
280 isolated_web_contents_->GetDevToolsTarget()->AttachClient( | |
281 isolated_devtools_client_.get()); | |
282 HeadlessAsyncDevTooledBrowserTest::DevToolsTargetReady(); | |
283 } | |
284 | |
285 void RunDevTooledTest() override { | |
286 load_observer_.reset(new LoadObserver( | |
287 devtools_client_.get(), | |
288 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstLoadComplete, | |
289 base::Unretained(this)))); | |
290 devtools_client_->GetPage()->Navigate( | |
291 embedded_test_server()->GetURL("/hello.html").spec()); | |
292 } | |
293 | |
294 void OnFirstLoadComplete() { | |
295 EXPECT_TRUE(load_observer_->navigation_succeeded()); | |
296 load_observer_.reset(new LoadObserver( | |
297 isolated_devtools_client_.get(), | |
298 base::Bind(&HeadlessBrowserContextIsolationTest::OnSecondLoadComplete, | |
299 base::Unretained(this)))); | |
300 isolated_devtools_client_->GetPage()->Navigate( | |
301 embedded_test_server()->GetURL("/hello.html").spec()); | |
302 } | |
303 | |
304 void OnSecondLoadComplete() { | |
305 EXPECT_TRUE(load_observer_->navigation_succeeded()); | |
306 load_observer_.reset(); | |
307 | |
308 devtools_client_->GetRuntime()->Evaluate( | |
309 base::StringPrintf("document.cookie = '%s'", kMainPageCookie), | |
310 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstSetCookieResult, | |
311 base::Unretained(this))); | |
312 } | |
313 | |
314 void OnFirstSetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) { | |
315 std::string cookie; | |
316 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); | |
317 EXPECT_EQ(kMainPageCookie, cookie); | |
318 | |
319 isolated_devtools_client_->GetRuntime()->Evaluate( | |
320 base::StringPrintf("document.cookie = '%s'", kIsolatedPageCookie), | |
321 base::Bind( | |
322 &HeadlessBrowserContextIsolationTest::OnSecondSetCookieResult, | |
323 base::Unretained(this))); | |
324 } | |
325 | |
326 void OnSecondSetCookieResult( | |
327 std::unique_ptr<runtime::EvaluateResult> result) { | |
328 std::string cookie; | |
329 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); | |
330 EXPECT_EQ(kIsolatedPageCookie, cookie); | |
331 | |
332 devtools_client_->GetRuntime()->Evaluate( | |
333 "document.cookie", | |
334 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstGetCookieResult, | |
335 base::Unretained(this))); | |
336 } | |
337 | |
338 void OnFirstGetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) { | |
339 std::string cookie; | |
340 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); | |
341 EXPECT_EQ(kMainPageCookie, cookie); | |
342 | |
343 isolated_devtools_client_->GetRuntime()->Evaluate( | |
344 "document.cookie", | |
345 base::Bind( | |
346 &HeadlessBrowserContextIsolationTest::OnSecondGetCookieResult, | |
347 base::Unretained(this))); | |
348 } | |
349 | |
350 void OnSecondGetCookieResult( | |
351 std::unique_ptr<runtime::EvaluateResult> result) { | |
352 std::string cookie; | |
353 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); | |
354 EXPECT_EQ(kIsolatedPageCookie, cookie); | |
355 FinishTest(); | |
356 } | |
357 | |
358 void FinishTest() { | |
359 isolated_web_contents_->RemoveObserver(this); | |
360 isolated_web_contents_->Close(); | |
361 browser_context_.reset(); | |
362 FinishAsynchronousTest(); | |
363 } | |
364 | |
365 private: | |
366 std::unique_ptr<HeadlessBrowserContext> browser_context_; | |
367 HeadlessWebContents* isolated_web_contents_; | |
368 std::unique_ptr<HeadlessDevToolsClient> isolated_devtools_client_; | |
369 std::unique_ptr<LoadObserver> load_observer_; | |
370 }; | |
371 | |
372 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessBrowserContextIsolationTest); | |
373 | |
223 } // namespace headless | 374 } // namespace headless |
OLD | NEW |