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