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 : web_contents2_(nullptr), |
| 264 devtools_client2_(HeadlessDevToolsClient::Create()) { |
| 265 EXPECT_TRUE(embedded_test_server()->Start()); |
| 266 } |
| 267 |
| 268 // HeadlessWebContentsObserver implementation: |
| 269 void DevToolsTargetReady() override { |
| 270 if (!web_contents2_) { |
| 271 browser_context_ = browser()->CreateBrowserContextBuilder().Build(); |
| 272 web_contents2_ = browser() |
| 273 ->CreateWebContentsBuilder() |
| 274 .SetBrowserContext(browser_context_.get()) |
| 275 .Build(); |
| 276 web_contents2_->AddObserver(this); |
| 277 return; |
| 278 } |
| 279 |
| 280 web_contents2_->GetDevToolsTarget()->AttachClient(devtools_client2_.get()); |
| 281 HeadlessAsyncDevTooledBrowserTest::DevToolsTargetReady(); |
| 282 } |
| 283 |
| 284 void RunDevTooledTest() override { |
| 285 load_observer_.reset(new LoadObserver( |
| 286 devtools_client_.get(), |
| 287 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstLoadComplete, |
| 288 base::Unretained(this)))); |
| 289 devtools_client_->GetPage()->Navigate( |
| 290 embedded_test_server()->GetURL("/hello.html").spec()); |
| 291 } |
| 292 |
| 293 void OnFirstLoadComplete() { |
| 294 EXPECT_TRUE(load_observer_->navigation_succeeded()); |
| 295 load_observer_.reset(new LoadObserver( |
| 296 devtools_client2_.get(), |
| 297 base::Bind(&HeadlessBrowserContextIsolationTest::OnSecondLoadComplete, |
| 298 base::Unretained(this)))); |
| 299 devtools_client2_->GetPage()->Navigate( |
| 300 embedded_test_server()->GetURL("/hello.html").spec()); |
| 301 } |
| 302 |
| 303 void OnSecondLoadComplete() { |
| 304 EXPECT_TRUE(load_observer_->navigation_succeeded()); |
| 305 load_observer_.reset(); |
| 306 |
| 307 devtools_client_->GetRuntime()->Evaluate( |
| 308 base::StringPrintf("document.cookie = '%s'", kMainPageCookie), |
| 309 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstSetCookieResult, |
| 310 base::Unretained(this))); |
| 311 } |
| 312 |
| 313 void OnFirstSetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) { |
| 314 std::string cookie; |
| 315 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); |
| 316 EXPECT_EQ(kMainPageCookie, cookie); |
| 317 |
| 318 devtools_client2_->GetRuntime()->Evaluate( |
| 319 base::StringPrintf("document.cookie = '%s'", kIsolatedPageCookie), |
| 320 base::Bind( |
| 321 &HeadlessBrowserContextIsolationTest::OnSecondSetCookieResult, |
| 322 base::Unretained(this))); |
| 323 } |
| 324 |
| 325 void OnSecondSetCookieResult( |
| 326 std::unique_ptr<runtime::EvaluateResult> result) { |
| 327 std::string cookie; |
| 328 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); |
| 329 EXPECT_EQ(kIsolatedPageCookie, cookie); |
| 330 |
| 331 devtools_client_->GetRuntime()->Evaluate( |
| 332 "document.cookie", |
| 333 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstGetCookieResult, |
| 334 base::Unretained(this))); |
| 335 } |
| 336 |
| 337 void OnFirstGetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) { |
| 338 std::string cookie; |
| 339 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); |
| 340 EXPECT_EQ(kMainPageCookie, cookie); |
| 341 |
| 342 devtools_client2_->GetRuntime()->Evaluate( |
| 343 "document.cookie", |
| 344 base::Bind( |
| 345 &HeadlessBrowserContextIsolationTest::OnSecondGetCookieResult, |
| 346 base::Unretained(this))); |
| 347 } |
| 348 |
| 349 void OnSecondGetCookieResult( |
| 350 std::unique_ptr<runtime::EvaluateResult> result) { |
| 351 std::string cookie; |
| 352 EXPECT_TRUE(result->GetResult()->GetValue()->GetAsString(&cookie)); |
| 353 EXPECT_EQ(kIsolatedPageCookie, cookie); |
| 354 FinishTest(); |
| 355 } |
| 356 |
| 357 void FinishTest() { |
| 358 web_contents2_->RemoveObserver(this); |
| 359 web_contents2_->Close(); |
| 360 browser_context_.reset(); |
| 361 FinishAsynchronousTest(); |
| 362 } |
| 363 |
| 364 private: |
| 365 std::unique_ptr<HeadlessBrowserContext> browser_context_; |
| 366 HeadlessWebContents* web_contents2_; |
| 367 std::unique_ptr<HeadlessDevToolsClient> devtools_client2_; |
| 368 std::unique_ptr<LoadObserver> load_observer_; |
| 369 }; |
| 370 |
| 371 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessBrowserContextIsolationTest); |
| 372 |
223 } // namespace headless | 373 } // namespace headless |
OLD | NEW |