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 #include <string> | 6 #include <string> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/json/json_writer.h" |
10 #include "content/public/test/browser_test.h" | 11 #include "content/public/test/browser_test.h" |
11 #include "headless/public/devtools/domains/page.h" | 12 #include "headless/public/devtools/domains/page.h" |
12 #include "headless/public/devtools/domains/runtime.h" | 13 #include "headless/public/devtools/domains/runtime.h" |
13 #include "headless/public/devtools/domains/security.h" | 14 #include "headless/public/devtools/domains/security.h" |
14 #include "headless/public/headless_browser.h" | 15 #include "headless/public/headless_browser.h" |
15 #include "headless/public/headless_devtools_client.h" | 16 #include "headless/public/headless_devtools_client.h" |
16 #include "headless/public/headless_tab_socket.h" | 17 #include "headless/public/headless_tab_socket.h" |
17 #include "headless/public/headless_web_contents.h" | 18 #include "headless/public/headless_web_contents.h" |
18 #include "headless/test/headless_browser_test.h" | 19 #include "headless/test/headless_browser_test.h" |
19 #include "printing/features/features.h" | 20 #include "printing/features/features.h" |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 288 |
288 devtools_client_->GetSecurity()->GetExperimental()->Disable( | 289 devtools_client_->GetSecurity()->GetExperimental()->Disable( |
289 security::DisableParams::Builder().Build()); | 290 security::DisableParams::Builder().Build()); |
290 devtools_client_->GetSecurity()->GetExperimental()->RemoveObserver(this); | 291 devtools_client_->GetSecurity()->GetExperimental()->RemoveObserver(this); |
291 FinishAsynchronousTest(); | 292 FinishAsynchronousTest(); |
292 } | 293 } |
293 }; | 294 }; |
294 | 295 |
295 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsSecurityTest); | 296 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsSecurityTest); |
296 | 297 |
297 class HeadlessTabSocketTest : public HeadlessAsyncDevTooledBrowserTest, | 298 class GetHeadlessTabSocketButNoTabSocket |
298 public HeadlessTabSocket::Listener { | 299 : public HeadlessAsyncDevTooledBrowserTest { |
299 public: | 300 public: |
300 void SetUp() override { | 301 void SetUp() override { |
301 options()->mojo_service_names.insert("headless::TabSocket"); | 302 options()->mojo_service_names.insert("headless::TabSocket"); |
| 303 HeadlessAsyncDevTooledBrowserTest::SetUp(); |
| 304 } |
| 305 |
| 306 void RunDevTooledTest() override { |
| 307 ASSERT_THAT(web_contents_->GetHeadlessTabSocket(), testing::IsNull()); |
| 308 FinishAsynchronousTest(); |
| 309 } |
| 310 |
| 311 bool GetCreateTabSocket() override { return false; } |
| 312 }; |
| 313 |
| 314 HEADLESS_ASYNC_DEVTOOLED_TEST_F(GetHeadlessTabSocketButNoTabSocket); |
| 315 |
| 316 class HeadlessMainWorldTabSocketTest : public HeadlessAsyncDevTooledBrowserTest, |
| 317 public HeadlessTabSocket::Listener { |
| 318 public: |
| 319 void SetUp() override { |
| 320 options()->mojo_service_names.insert("headless::TabSocket"); |
302 HeadlessAsyncDevTooledBrowserTest::SetUp(); | 321 HeadlessAsyncDevTooledBrowserTest::SetUp(); |
303 } | 322 } |
304 | 323 |
305 void RunDevTooledTest() override { | 324 void RunDevTooledTest() override { |
306 devtools_client_->GetRuntime()->Evaluate( | 325 devtools_client_->GetRuntime()->Evaluate( |
307 R"(window.TabSocket.onmessage = | 326 R"(window.TabSocket.onmessage = |
308 function(event) { | 327 function(message) { |
309 window.TabSocket.send( | 328 window.TabSocket.send('Embedder sent us: ' + message); |
310 'Embedder sent us: ' + event.detail.message); | |
311 }; | 329 }; |
312 )"); | 330 )"); |
313 | 331 |
314 HeadlessTabSocket* headless_tab_socket = | 332 HeadlessTabSocket* headless_tab_socket = |
315 web_contents_->GetHeadlessTabSocket(); | 333 web_contents_->GetHeadlessTabSocket(); |
316 DCHECK(headless_tab_socket); | 334 DCHECK(headless_tab_socket); |
317 | 335 |
318 headless_tab_socket->SendMessageToTab("Hello"); | 336 headless_tab_socket->SendMessageToTab("Hello"); |
319 headless_tab_socket->SetListener(this); | 337 headless_tab_socket->SetListener(this); |
320 } | 338 } |
321 | 339 |
322 void OnMessageFromTab(const std::string& message) override { | 340 void OnMessageFromTab(const std::string& message) override { |
323 EXPECT_EQ("Embedder sent us: Hello", message); | 341 EXPECT_EQ("Embedder sent us: Hello", message); |
324 FinishAsynchronousTest(); | 342 FinishAsynchronousTest(); |
325 } | 343 } |
326 | 344 |
327 bool GetCreateTabSocket() override { return true; } | 345 bool GetCreateTabSocket() override { return true; } |
| 346 bool GetCreateTabSocketOnlyForIsolatedWorld() override { return false; } |
328 }; | 347 }; |
329 | 348 |
330 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessTabSocketTest); | 349 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessMainWorldTabSocketTest); |
| 350 |
| 351 class HeadlessMainWorldTabSocketNotThereTest |
| 352 : public HeadlessAsyncDevTooledBrowserTest, |
| 353 public HeadlessTabSocket::Listener { |
| 354 public: |
| 355 void SetUp() override { |
| 356 options()->mojo_service_names.insert("headless::TabSocket"); |
| 357 HeadlessAsyncDevTooledBrowserTest::SetUp(); |
| 358 } |
| 359 |
| 360 void RunDevTooledTest() override { |
| 361 // We expect this to fail because the TabSocket is being injected into |
| 362 // isolated worlds. |
| 363 devtools_client_->GetRuntime()->Evaluate( |
| 364 "window.TabSocket.send('This should not work!');", |
| 365 base::Bind(&HeadlessMainWorldTabSocketNotThereTest::EvaluateResult, |
| 366 base::Unretained(this))); |
| 367 |
| 368 HeadlessTabSocket* headless_tab_socket = |
| 369 web_contents_->GetHeadlessTabSocket(); |
| 370 DCHECK(headless_tab_socket); |
| 371 |
| 372 headless_tab_socket->SetListener(this); |
| 373 } |
| 374 |
| 375 void EvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { |
| 376 EXPECT_TRUE(result->HasExceptionDetails()); |
| 377 FinishAsynchronousTest(); |
| 378 } |
| 379 |
| 380 void OnMessageFromTab(const std::string&) override { |
| 381 FAIL() << "Should not receive a message from the tab!"; |
| 382 FinishAsynchronousTest(); |
| 383 } |
| 384 |
| 385 bool GetCreateTabSocket() override { return true; } |
| 386 bool GetCreateTabSocketOnlyForIsolatedWorld() override { return true; } |
| 387 }; |
| 388 |
| 389 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessMainWorldTabSocketNotThereTest); |
| 390 |
| 391 class HeadlessIsolatedWorldTabSocketTest |
| 392 : public HeadlessAsyncDevTooledBrowserTest, |
| 393 public HeadlessTabSocket::Listener, |
| 394 public runtime::Observer { |
| 395 public: |
| 396 void SetUp() override { |
| 397 options()->mojo_service_names.insert("headless::TabSocket"); |
| 398 HeadlessAsyncDevTooledBrowserTest::SetUp(); |
| 399 } |
| 400 |
| 401 void RunDevTooledTest() override { |
| 402 devtools_client_->GetRuntime()->AddObserver(this); |
| 403 devtools_client_->GetRuntime()->Enable(); |
| 404 |
| 405 devtools_client_->GetPage()->GetExperimental()->GetResourceTree( |
| 406 page::GetResourceTreeParams::Builder().Build(), |
| 407 base::Bind(&HeadlessIsolatedWorldTabSocketTest::OnResourceTree, |
| 408 base::Unretained(this))); |
| 409 |
| 410 HeadlessTabSocket* headless_tab_socket = |
| 411 web_contents_->GetHeadlessTabSocket(); |
| 412 DCHECK(headless_tab_socket); |
| 413 headless_tab_socket->SendMessageToTab("Hello!!!"); |
| 414 headless_tab_socket->SetListener(this); |
| 415 } |
| 416 |
| 417 void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { |
| 418 main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); |
| 419 devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( |
| 420 page::CreateIsolatedWorldParams::Builder() |
| 421 .SetFrameId(main_frame_id_) |
| 422 .Build()); |
| 423 } |
| 424 |
| 425 void OnExecutionContextCreated( |
| 426 const runtime::ExecutionContextCreatedParams& params) override { |
| 427 const base::DictionaryValue* dictionary; |
| 428 std::string frame_id; |
| 429 bool is_main_world; |
| 430 // If the isolated world was created then eval some script in it. |
| 431 if (params.GetContext()->HasAuxData() && |
| 432 params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary) && |
| 433 dictionary->GetString("frameId", &frame_id) && |
| 434 frame_id == main_frame_id_ && |
| 435 dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { |
| 436 devtools_client_->GetRuntime()->Evaluate( |
| 437 runtime::EvaluateParams::Builder() |
| 438 .SetExpression( |
| 439 R"(window.TabSocket.onmessage = |
| 440 function(message) { |
| 441 TabSocket.send('Embedder sent us: ' + message); |
| 442 }; |
| 443 )") |
| 444 .SetContextId(params.GetContext()->GetId()) |
| 445 .Build()); |
| 446 } |
| 447 } |
| 448 |
| 449 void OnMessageFromTab(const std::string& message) override { |
| 450 EXPECT_EQ("Embedder sent us: Hello!!!", message); |
| 451 FinishAsynchronousTest(); |
| 452 } |
| 453 |
| 454 bool GetCreateTabSocket() override { return true; } |
| 455 bool GetCreateTabSocketOnlyForIsolatedWorld() override { return true; } |
| 456 |
| 457 private: |
| 458 std::string main_frame_id_; |
| 459 }; |
| 460 |
| 461 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessIsolatedWorldTabSocketTest); |
| 462 |
| 463 class HeadlessIsolatedWorldTabSocketNotThereTest |
| 464 : public HeadlessAsyncDevTooledBrowserTest, |
| 465 public HeadlessTabSocket::Listener, |
| 466 public runtime::Observer { |
| 467 public: |
| 468 void SetUp() override { |
| 469 options()->mojo_service_names.insert("headless::TabSocket"); |
| 470 HeadlessAsyncDevTooledBrowserTest::SetUp(); |
| 471 } |
| 472 |
| 473 void RunDevTooledTest() override { |
| 474 devtools_client_->GetRuntime()->AddObserver(this); |
| 475 devtools_client_->GetRuntime()->Enable(); |
| 476 |
| 477 devtools_client_->GetPage()->GetExperimental()->GetResourceTree( |
| 478 page::GetResourceTreeParams::Builder().Build(), |
| 479 base::Bind(&HeadlessIsolatedWorldTabSocketNotThereTest::OnResourceTree, |
| 480 base::Unretained(this))); |
| 481 |
| 482 HeadlessTabSocket* headless_tab_socket = |
| 483 web_contents_->GetHeadlessTabSocket(); |
| 484 DCHECK(headless_tab_socket); |
| 485 headless_tab_socket->SendMessageToTab("Hello!!!"); |
| 486 headless_tab_socket->SetListener(this); |
| 487 } |
| 488 |
| 489 void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { |
| 490 main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); |
| 491 devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( |
| 492 page::CreateIsolatedWorldParams::Builder() |
| 493 .SetFrameId(main_frame_id_) |
| 494 .Build()); |
| 495 } |
| 496 |
| 497 void OnExecutionContextCreated( |
| 498 const runtime::ExecutionContextCreatedParams& params) override { |
| 499 const base::DictionaryValue* dictionary; |
| 500 std::string frame_id; |
| 501 bool is_main_world; |
| 502 // If the isolated world was created then eval some script in it. |
| 503 if (params.GetContext()->HasAuxData() && |
| 504 params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary) && |
| 505 dictionary->GetString("frameId", &frame_id) && |
| 506 frame_id == main_frame_id_ && |
| 507 dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { |
| 508 // We expect this to fail because the TabSocket is being injected into the |
| 509 // main world. |
| 510 devtools_client_->GetRuntime()->Evaluate( |
| 511 runtime::EvaluateParams::Builder() |
| 512 .SetExpression("window.TabSocket.send('This should not work!');") |
| 513 .SetContextId(params.GetContext()->GetId()) |
| 514 .Build(), |
| 515 base::Bind( |
| 516 &HeadlessIsolatedWorldTabSocketNotThereTest::EvaluateResult, |
| 517 base::Unretained(this))); |
| 518 } |
| 519 } |
| 520 |
| 521 void EvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { |
| 522 EXPECT_TRUE(result->HasExceptionDetails()); |
| 523 FinishAsynchronousTest(); |
| 524 } |
| 525 |
| 526 void OnMessageFromTab(const std::string&) override { |
| 527 FAIL() << "Should not receive a message from the tab!"; |
| 528 FinishAsynchronousTest(); |
| 529 } |
| 530 |
| 531 bool GetCreateTabSocket() override { return true; } |
| 532 bool GetCreateTabSocketOnlyForIsolatedWorld() override { return false; } |
| 533 |
| 534 private: |
| 535 std::string main_frame_id_; |
| 536 }; |
| 537 |
| 538 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessIsolatedWorldTabSocketNotThereTest); |
331 | 539 |
332 } // namespace headless | 540 } // namespace headless |
OLD | NEW |