OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
7 #include "base/json/json_reader.h" | 7 #include "base/json/json_reader.h" |
8 #include "base/run_loop.h" | 8 #include "base/run_loop.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/test/test_timeouts.h" | 10 #include "base/test/test_timeouts.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } // namespace | 79 } // namespace |
80 | 80 |
81 class HTMLFrameTest : public ViewManagerTestBase { | 81 class HTMLFrameTest : public ViewManagerTestBase { |
82 public: | 82 public: |
83 HTMLFrameTest() {} | 83 HTMLFrameTest() {} |
84 ~HTMLFrameTest() override {} | 84 ~HTMLFrameTest() override {} |
85 | 85 |
86 protected: | 86 protected: |
87 // Creates the frame tree showing an empty page at the root and adds (via | 87 // Creates the frame tree showing an empty page at the root and adds (via |
88 // script) a frame showing the same empty page. | 88 // script) a frame showing the same empty page. |
89 Frame* LoadEmptyPageAndCreateFrame() { | 89 Frame* LoadEmptyPageAndCreateFrame(mandoline::FrameTreeDelegate* delegate) { |
90 View* embed_view = window_manager()->CreateView(); | 90 View* embed_view = window_manager()->CreateView(); |
91 FrameConnection* root_connection = InitFrameTree( | 91 FrameConnection* root_connection = InitFrameTree( |
92 embed_view, nullptr, "http://127.0.0.1:%u/files/empty_page2.html"); | 92 embed_view, delegate, "http://127.0.0.1:%u/files/empty_page2.html"); |
93 const std::string frame_text = | 93 const std::string frame_text = |
94 GetFrameText(root_connection->application_connection()); | 94 GetFrameText(root_connection->application_connection()); |
95 if (frame_text != "child2") { | 95 if (frame_text != "child2") { |
96 ADD_FAILURE() << "unexpected text " << frame_text; | 96 ADD_FAILURE() << "unexpected text " << frame_text; |
97 return nullptr; | 97 return nullptr; |
98 } | 98 } |
99 | 99 |
100 return CreateEmptyChildFrame(frame_tree_->root()); | 100 return CreateEmptyChildFrame(frame_tree_->root()); |
101 } | 101 } |
102 | 102 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 ASSERT_TRUE(child_frame->user_data()); | 322 ASSERT_TRUE(child_frame->user_data()); |
323 ASSERT_EQ("child2", | 323 ASSERT_EQ("child2", |
324 GetFrameText(static_cast<FrameConnection*>(child_frame->user_data()) | 324 GetFrameText(static_cast<FrameConnection*>(child_frame->user_data()) |
325 ->application_connection())); | 325 ->application_connection())); |
326 } | 326 } |
327 | 327 |
328 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndVerifyParent) { | 328 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndVerifyParent) { |
329 if (!EnableOOPIFs()) | 329 if (!EnableOOPIFs()) |
330 return; | 330 return; |
331 | 331 |
332 Frame* child_frame = LoadEmptyPageAndCreateFrame(); | 332 Frame* child_frame = LoadEmptyPageAndCreateFrame(nullptr); |
333 ASSERT_TRUE(child_frame); | 333 ASSERT_TRUE(child_frame); |
334 | 334 |
335 mojo::ApplicationConnection* child_frame_connection = | 335 mojo::ApplicationConnection* child_frame_connection = |
336 ApplicationConnectionForFrame(child_frame); | 336 ApplicationConnectionForFrame(child_frame); |
337 | 337 |
338 ASSERT_EQ("child", GetFrameText(child_frame_connection)); | 338 ASSERT_EQ("child", GetFrameText(child_frame_connection)); |
339 // The child's parent should not be itself: | 339 // The child's parent should not be itself: |
340 const char kGetWindowParentNameScript[] = | 340 const char kGetWindowParentNameScript[] = |
341 "window.parent == window ? 'parent is self' : 'parent not self';"; | 341 "window.parent == window ? 'parent is self' : 'parent not self';"; |
342 scoped_ptr<base::Value> parent_value( | 342 scoped_ptr<base::Value> parent_value( |
343 ExecuteScript(child_frame_connection, kGetWindowParentNameScript)); | 343 ExecuteScript(child_frame_connection, kGetWindowParentNameScript)); |
344 ASSERT_TRUE(parent_value->IsType(base::Value::TYPE_LIST)); | 344 ASSERT_TRUE(parent_value->IsType(base::Value::TYPE_LIST)); |
345 base::ListValue* parent_list; | 345 base::ListValue* parent_list; |
346 ASSERT_TRUE(parent_value->GetAsList(&parent_list)); | 346 ASSERT_TRUE(parent_value->GetAsList(&parent_list)); |
347 ASSERT_EQ(1u, parent_list->GetSize()); | 347 ASSERT_EQ(1u, parent_list->GetSize()); |
348 std::string parent_name; | 348 std::string parent_name; |
349 ASSERT_TRUE(parent_list->GetString(0u, &parent_name)); | 349 ASSERT_TRUE(parent_list->GetString(0u, &parent_name)); |
350 EXPECT_EQ("parent not self", parent_name); | 350 EXPECT_EQ("parent not self", parent_name); |
351 } | 351 } |
352 | 352 |
353 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndSeeNameChange) { | 353 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndSeeNameChange) { |
354 if (!EnableOOPIFs()) | 354 if (!EnableOOPIFs()) |
355 return; | 355 return; |
356 | 356 |
357 Frame* child_frame = LoadEmptyPageAndCreateFrame(); | 357 Frame* child_frame = LoadEmptyPageAndCreateFrame(nullptr); |
358 ASSERT_TRUE(child_frame); | 358 ASSERT_TRUE(child_frame); |
359 | 359 |
360 mojo::ApplicationConnection* child_frame_connection = | 360 mojo::ApplicationConnection* child_frame_connection = |
361 ApplicationConnectionForFrame(child_frame); | 361 ApplicationConnectionForFrame(child_frame); |
362 | 362 |
363 // Change the name of the child's window. | 363 // Change the name of the child's window. |
364 ExecuteScript(child_frame_connection, "window.name = 'new_child';"); | 364 ExecuteScript(child_frame_connection, "window.name = 'new_child';"); |
365 | 365 |
366 // Eventually the parent should see the change. There is no convenient way | 366 // Eventually the parent should see the change. There is no convenient way |
367 // to observe this change, so we repeatedly ask for it and timeout if we | 367 // to observe this change, so we repeatedly ask for it and timeout if we |
(...skipping 18 matching lines...) Expand all Loading... |
386 TestTimeouts::action_timeout()); | 386 TestTimeouts::action_timeout()); |
387 EXPECT_EQ("found frame", find_window_result); | 387 EXPECT_EQ("found frame", find_window_result); |
388 } | 388 } |
389 | 389 |
390 // Triggers dynamic addition and removal of a frame. | 390 // Triggers dynamic addition and removal of a frame. |
391 TEST_F(HTMLFrameTest, FrameTreeOfThreeLevels) { | 391 TEST_F(HTMLFrameTest, FrameTreeOfThreeLevels) { |
392 if (!EnableOOPIFs()) | 392 if (!EnableOOPIFs()) |
393 return; | 393 return; |
394 | 394 |
395 // Create a child frame, and in that child frame create another child frame. | 395 // Create a child frame, and in that child frame create another child frame. |
396 Frame* child_frame = LoadEmptyPageAndCreateFrame(); | 396 Frame* child_frame = LoadEmptyPageAndCreateFrame(nullptr); |
397 ASSERT_TRUE(child_frame); | 397 ASSERT_TRUE(child_frame); |
398 | 398 |
399 ASSERT_TRUE(CreateEmptyChildFrame(child_frame)); | 399 ASSERT_TRUE(CreateEmptyChildFrame(child_frame)); |
400 | 400 |
401 // Make sure the parent can see the child and child's child. There is no | 401 // Make sure the parent can see the child and child's child. There is no |
402 // convenient way to observe this change, so we repeatedly ask for it and | 402 // convenient way to observe this change, so we repeatedly ask for it and |
403 // timeout if we never get the right value. | 403 // timeout if we never get the right value. |
404 const char kGetChildChildFrameCount[] = | 404 const char kGetChildChildFrameCount[] = |
405 "if (window.frames.length > 0)" | 405 "if (window.frames.length > 0)" |
406 " window.frames[0].frames.length.toString();" | 406 " window.frames[0].frames.length.toString();" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 script_value_as_list->GetSize() == 1) { | 440 script_value_as_list->GetSize() == 1) { |
441 script_value_as_list->GetString(0u, &child_child_frame_count); | 441 script_value_as_list->GetString(0u, &child_child_frame_count); |
442 } | 442 } |
443 } | 443 } |
444 } while (child_child_frame_count != "0" && | 444 } while (child_child_frame_count != "0" && |
445 base::TimeTicks::Now() - start_time < | 445 base::TimeTicks::Now() - start_time < |
446 TestTimeouts::action_timeout()); | 446 TestTimeouts::action_timeout()); |
447 ASSERT_EQ("0", child_child_frame_count); | 447 ASSERT_EQ("0", child_child_frame_count); |
448 } | 448 } |
449 | 449 |
| 450 // Verifies PostMessage() works across frames. |
| 451 TEST_F(HTMLFrameTest, PostMessage) { |
| 452 if (!EnableOOPIFs()) |
| 453 return; |
| 454 |
| 455 mandoline::TestFrameTreeDelegate frame_tree_delegate; |
| 456 Frame* child_frame = LoadEmptyPageAndCreateFrame(&frame_tree_delegate); |
| 457 ASSERT_TRUE(child_frame); |
| 458 |
| 459 mojo::ApplicationConnection* child_frame_connection = |
| 460 ApplicationConnectionForFrame(child_frame); |
| 461 ASSERT_EQ("child", GetFrameText(child_frame_connection)); |
| 462 |
| 463 // Register an event handler in the child frame. |
| 464 const char kRegisterPostMessageHandler[] = |
| 465 "window.messageData = null;" |
| 466 "function messageFunction(event) {" |
| 467 " window.messageData = event.data;" |
| 468 "}" |
| 469 "window.addEventListener('message', messageFunction, false);"; |
| 470 ExecuteScript(child_frame_connection, kRegisterPostMessageHandler); |
| 471 |
| 472 // Post a message from the parent to the child. |
| 473 const char kPostMessageFromParent[] = |
| 474 "window.frames[0].postMessage('hello from parent', '*');"; |
| 475 ExecuteScript(ApplicationConnectionForFrame(frame_tree_->root()), |
| 476 kPostMessageFromParent); |
| 477 |
| 478 // Wait for the child frame to see the message. |
| 479 const base::TimeTicks start_time(base::TimeTicks::Now()); |
| 480 std::string message_in_child; |
| 481 do { |
| 482 const char kGetMessageData[] = "window.messageData;"; |
| 483 scoped_ptr<base::Value> script_value( |
| 484 ExecuteScript(child_frame_connection, kGetMessageData)); |
| 485 if (script_value->IsType(base::Value::TYPE_LIST)) { |
| 486 base::ListValue* script_value_as_list; |
| 487 if (script_value->GetAsList(&script_value_as_list) && |
| 488 script_value_as_list->GetSize() == 1) { |
| 489 script_value_as_list->GetString(0u, &message_in_child); |
| 490 } |
| 491 } |
| 492 } while (message_in_child != "hello from parent" && |
| 493 base::TimeTicks::Now() - start_time < |
| 494 TestTimeouts::action_timeout()); |
| 495 EXPECT_EQ("hello from parent", message_in_child); |
| 496 } |
| 497 |
450 } // namespace mojo | 498 } // namespace mojo |
OLD | NEW |