Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: content/browser/frame_host/navigation_controller_impl_browsertest.cc

Issue 2191543003: Remove existing FrameNavigationEntry when new named frame is added. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove extra pointer in test. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/frame_host/navigation_controller_impl.h" 5 #include "content/browser/frame_host/navigation_controller_impl.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 26 matching lines...) Expand all
37 #include "content/public/test/test_navigation_observer.h" 37 #include "content/public/test/test_navigation_observer.h"
38 #include "content/public/test/test_utils.h" 38 #include "content/public/test/test_utils.h"
39 #include "content/shell/browser/shell.h" 39 #include "content/shell/browser/shell.h"
40 #include "content/shell/common/shell_switches.h" 40 #include "content/shell/common/shell_switches.h"
41 #include "content/test/content_browser_test_utils_internal.h" 41 #include "content/test/content_browser_test_utils_internal.h"
42 #include "content/test/test_frame_navigation_observer.h" 42 #include "content/test/test_frame_navigation_observer.h"
43 #include "net/dns/mock_host_resolver.h" 43 #include "net/dns/mock_host_resolver.h"
44 #include "net/test/embedded_test_server/embedded_test_server.h" 44 #include "net/test/embedded_test_server/embedded_test_server.h"
45 #include "net/test/url_request/url_request_failed_job.h" 45 #include "net/test/url_request/url_request_failed_job.h"
46 46
47 namespace {
48
49 static std::string kAddNamedFrameScript =
50 "var f = document.createElement('iframe');"
51 "f.name = 'foo-frame-name';"
52 "document.body.appendChild(f);";
53 static std::string kAddFrameScript =
54 "var f = document.createElement('iframe');"
55 "document.body.appendChild(f);";
56 static std::string kRemoveFrameScript =
57 "var f = document.querySelector('iframe');"
58 "f.parentNode.removeChild(f);";
59
60 } // namespace
61
47 namespace content { 62 namespace content {
48 63
49 class NavigationControllerBrowserTest : public ContentBrowserTest { 64 class NavigationControllerBrowserTest : public ContentBrowserTest {
50 protected: 65 protected:
51 void SetUpOnMainThread() override { 66 void SetUpOnMainThread() override {
52 host_resolver()->AddRule("*", "127.0.0.1"); 67 host_resolver()->AddRule("*", "127.0.0.1");
53 ASSERT_TRUE(embedded_test_server()->Start()); 68 ASSERT_TRUE(embedded_test_server()->Start());
54 } 69 }
55 }; 70 };
56 71
(...skipping 5362 matching lines...) Expand 10 before | Expand all | Expand 10 after
5419 // the body of the page. 5434 // the body of the page.
5420 std::string body; 5435 std::string body;
5421 EXPECT_TRUE(ExecuteScriptAndExtractString( 5436 EXPECT_TRUE(ExecuteScriptAndExtractString(
5422 shell()->web_contents(), 5437 shell()->web_contents(),
5423 "window.domAutomationController.send(" 5438 "window.domAutomationController.send("
5424 "document.getElementsByTagName('pre')[0].innerText);", 5439 "document.getElementsByTagName('pre')[0].innerText);",
5425 &body)); 5440 &body));
5426 EXPECT_EQ("text=value\n", body); 5441 EXPECT_EQ("text=value\n", body);
5427 } 5442 }
5428 5443
5444 // Tests that inserting a named subframe into the FrameTree clears any
5445 // previously existing FrameNavigationEntry objects for the same name.
5446 // See https://crbug.com/628677.
5447 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
5448 EnsureFrameNavigationEntriesClearedOnMismatch) {
5449 WebContentsImpl* web_contents =
5450 static_cast<WebContentsImpl*>(shell()->web_contents());
5451 NavigationControllerImpl& controller = web_contents->GetController();
5452 FrameTreeNode* root = web_contents->GetFrameTree()->root();
5453
5454 // Start by navigating to a page with complex frame hierarchy.
5455 GURL start_url(embedded_test_server()->GetURL("/frame_tree/top.html"));
5456 EXPECT_TRUE(NavigateToURL(shell(), start_url));
5457 EXPECT_EQ(3U, root->child_count());
5458 EXPECT_EQ(2U, root->child_at(0)->child_count());
5459
5460 NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
5461
5462 // Verify only the parts of the NavigationEntry affected by this test.
5463 {
5464 // * Main frame has 3 subframes.
5465 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root);
5466 EXPECT_NE(nullptr, root_entry);
5467 EXPECT_EQ("", root_entry->frame_unique_name());
5468 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5469 EXPECT_EQ(3U, entry->root_node()->children.size());
5470
5471 // * The first child of the main frame is named and has two more children.
5472 FrameTreeNode* frame = root->child_at(0);
5473 FrameNavigationEntry* frame_entry = entry->GetFrameEntry(frame);
5474 EXPECT_NE(nullptr, frame_entry);
5475 EXPECT_EQ("1-1-name", frame_entry->frame_unique_name());
5476 EXPECT_EQ(2U, entry->root_node()->children[0]->children.size());
5477 }
5478 }
5479
5480 // Removing the first child of the main frame should remove the corresponding
5481 // FrameTreeNode.
5482 EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
5483 EXPECT_EQ(2U, root->child_count());
5484
5485 // However, the FrameNavigationEntry objects for the frame that was removed
5486 // should still be around.
5487 {
5488 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root);
5489 EXPECT_NE(nullptr, root_entry);
5490 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5491 EXPECT_EQ(3U, entry->root_node()->children.size());
5492 EXPECT_EQ(2U, entry->root_node()->children[0]->children.size());
5493 }
5494 }
5495
5496 // Now, insert a frame with the same name as the previously removed one
5497 // at a different layer of the frame tree.
5498 FrameTreeNode* subframe = root->child_at(1)->child_at(1)->child_at(0);
5499 EXPECT_EQ(2U, root->child_at(1)->child_count());
5500 EXPECT_EQ(0U, subframe->child_count());
5501 std::string add_matching_name_frame_script =
5502 "var f = document.createElement('iframe');"
5503 "f.name = '1-1-name';"
5504 "document.body.appendChild(f);";
5505 EXPECT_TRUE(ExecuteScript(subframe, add_matching_name_frame_script));
5506 EXPECT_EQ(1U, subframe->child_count());
5507
5508 // Verify that the FrameNavigationEntry for the original frame is now gone.
5509 {
5510 FrameNavigationEntry* root_entry = entry->GetFrameEntry(root);
5511 EXPECT_NE(nullptr, root_entry);
5512 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5513 EXPECT_EQ(2U, entry->root_node()->children.size());
5514 }
5515 }
5516 }
5517
5518 // Tests that sending a PageState update from a named subframe does not get
5519 // incorrectly set on previously existing FrameNavigationEntry for the same
5520 // name. It is similar to EnsureFrameNavigationEntriesClearedOnMismatch, but
5521 // doesn't navigate the iframes to real URLs when added to the DOM.
5522 // See https://crbug.com/628677.
5523 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
5524 EnsureFrameNavigationEntriesClearedOnMismatchNoSrc) {
5525 WebContentsImpl* web_contents =
5526 static_cast<WebContentsImpl*>(shell()->web_contents());
5527 FrameTreeNode* root = web_contents->GetFrameTree()->root();
5528
5529 GURL start_url(embedded_test_server()->GetURL("/title1.html"));
5530 EXPECT_TRUE(NavigateToURL(shell(), start_url));
5531 NavigationEntryImpl* nav_entry =
5532 web_contents->GetController().GetLastCommittedEntry();
5533
5534 EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
5535 EXPECT_EQ(1U, root->child_count());
5536 EXPECT_EQ("foo-frame-name", root->child_at(0)->frame_name());
5537
5538 EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
5539 EXPECT_EQ(0U, root->child_count());
5540
5541 // When a frame is removed from the page, the corresponding
5542 // FrameNavigationEntry is not removed. This is done intentionally to support
5543 // back-forward navigations in subframes and more intuitive UX on tab restore.
5544 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5545 EXPECT_EQ(1U, nav_entry->root_node()->children.size());
5546 FrameNavigationEntry* frame_entry =
5547 nav_entry->root_node()->children[0]->frame_entry.get();
5548 EXPECT_EQ("foo-frame-name", frame_entry->frame_unique_name());
5549 }
5550
5551 EXPECT_TRUE(ExecuteScript(root, kAddFrameScript));
5552 EXPECT_EQ(1U, root->child_count());
5553 EXPECT_NE("foo-frame-name", root->child_at(0)->frame_name());
5554
5555 // Add a nested frame with the previously used name.
5556 EXPECT_TRUE(ExecuteScript(root->child_at(0), kAddNamedFrameScript));
5557 EXPECT_EQ(1U, root->child_at(0)->child_count());
5558 EXPECT_EQ("foo-frame-name", root->child_at(0)->child_at(0)->frame_name());
5559
5560 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5561 EXPECT_EQ(1U, nav_entry->root_node()->children.size());
5562
5563 NavigationEntryImpl::TreeNode* tree_node =
5564 nav_entry->root_node()->children[0];
5565 EXPECT_EQ(1U, tree_node->children.size());
5566
5567 tree_node = tree_node->children[0];
5568 EXPECT_EQ(0U, tree_node->children.size());
5569 EXPECT_EQ("foo-frame-name", tree_node->frame_entry->frame_unique_name());
5570 }
5571
5572 EXPECT_TRUE(ExecuteScript(root->child_at(0), kRemoveFrameScript));
5573 EXPECT_EQ(0U, root->child_at(0)->child_count());
5574 }
5575
5576 // This test ensures that the comparison of tree position between a
5577 // FrameTreeNode and FrameNavigationEntry works correctly for matching
5578 // first-level frames.
5579 IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
5580 EnsureFirstLevelFrameNavigationEntriesMatch) {
5581 WebContentsImpl* web_contents =
5582 static_cast<WebContentsImpl*>(shell()->web_contents());
5583 FrameTreeNode* root = web_contents->GetFrameTree()->root();
5584 NavigationEntryImpl::TreeNode* tree_node = nullptr;
5585
5586 GURL start_url(embedded_test_server()->GetURL("/title1.html"));
5587 EXPECT_TRUE(NavigateToURL(shell(), start_url));
5588 NavigationEntryImpl* nav_entry =
5589 web_contents->GetController().GetLastCommittedEntry();
5590
5591 // Add, then remove a named frame. It will create a FrameNavigationEntry
5592 // for the name and leave it around.
5593 EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
5594 EXPECT_EQ(1U, root->child_count());
5595 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5596 EXPECT_EQ(1U, nav_entry->root_node()->children.size());
5597 tree_node = nav_entry->root_node()->children[0];
5598 }
5599
5600 EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
5601 EXPECT_EQ(0U, root->child_count());
5602 if (SiteIsolationPolicy::UseSubframeNavigationEntries())
5603 EXPECT_EQ(1U, nav_entry->root_node()->children.size());
5604
5605 // Add another frame with the same name as before. The matching logic
5606 // should consider them the same and result in the FrameNavigationEntry
5607 // being reused.
5608 EXPECT_TRUE(ExecuteScript(root, kAddNamedFrameScript));
5609 EXPECT_EQ(1U, root->child_count());
5610 if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
5611 EXPECT_EQ(1U, nav_entry->root_node()->children.size());
5612 EXPECT_EQ(tree_node, nav_entry->root_node()->children[0]);
5613 }
5614
5615 EXPECT_TRUE(ExecuteScript(root, kRemoveFrameScript));
5616 EXPECT_EQ(0U, root->child_count());
5617 }
5618
5429 } // namespace content 5619 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/frame_tree.cc ('k') | content/browser/frame_host/navigation_entry_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698