| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| #include "chrome/browser/search/instant_service.h" |
| #include "chrome/browser/search/instant_service_factory.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_commands.h" |
| #include "chrome/browser/ui/search/instant_test_base.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/network_session_configurator/common/network_switches.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/browser_test_utils.h" |
| #include "content/public/test/test_navigation_observer.h" |
| #include "net/dns/mock_host_resolver.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| class ThirdPartyNTPBrowserTest : public InProcessBrowserTest, |
| public InstantTestBase { |
| public: |
| ThirdPartyNTPBrowserTest() = default; |
| |
| void SetUpCommandLine(base::CommandLine* command_line) override { |
| command_line->AppendSwitch(switches::kIgnoreCertificateErrors); |
| } |
| |
| void SetUpOnMainThread() override { |
| InProcessBrowserTest::SetUpOnMainThread(); |
| host_resolver()->AddRule("*", "127.0.0.1"); |
| ASSERT_TRUE(https_test_server().Start()); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(ThirdPartyNTPBrowserTest); |
| }; |
| |
| // Verifies that a third party NTP can successfully embed the most visited |
| // iframe. |
| IN_PROC_BROWSER_TEST_F(ThirdPartyNTPBrowserTest, EmbeddedMostVisitedIframe) { |
| GURL base_url = |
| https_test_server().GetURL("ntp.com", "/instant_extended.html"); |
| GURL ntp_url = |
| https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html"); |
| InstantTestBase::Init(base_url, ntp_url, false); |
| SetupInstant(browser()); |
| |
| // Navigate to the NTP URL and verify that the resulting process is marked as |
| // an Instant process. |
| ui_test_utils::NavigateToURL(browser(), ntp_url); |
| content::WebContents* contents = |
| browser()->tab_strip_model()->GetActiveWebContents(); |
| InstantService* instant_service = |
| InstantServiceFactory::GetForProfile(browser()->profile()); |
| EXPECT_TRUE(instant_service->IsInstantProcess( |
| contents->GetMainFrame()->GetProcess()->GetID())); |
| |
| // Add a chrome-search://most-visited/title.html?rid=1&fs=0 subframe and |
| // verify that navigation completes successfully, with no kills. |
| content::TestNavigationObserver nav_observer(contents); |
| const char* kScript = R"( |
| const frame = document.createElement('iframe'); |
| frame.src = 'chrome-search://most-visited/title.html?rid=1&fs=0'; |
| document.body.appendChild(frame); |
| )"; |
| ASSERT_TRUE(content::ExecJs(contents, kScript)); |
| nav_observer.WaitForNavigationFinished(); |
| |
| // Verify that the subframe exists and has the expected origin. |
| ASSERT_EQ(2u, contents->GetAllFrames().size()); |
| content::RenderFrameHost* subframe = contents->GetAllFrames()[1]; |
| std::string subframe_origin; |
| ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
| subframe, "domAutomationController.send(window.origin)", |
| &subframe_origin)); |
| EXPECT_EQ("chrome-search://most-visited", subframe_origin); |
| } |
| |
| // Verifies that Chrome won't spawn a separate renderer process for |
| // every single NTP tab. This behavior goes all the way back to |
| // the initial commit [1] which achieved that behavior by forcing |
| // process-per-site mode for NTP tabs. It seems desirable to preserve this |
| // behavior going forward. |
| // |
| // [1] https://chromium.googlesource.com/chromium/src/+/09911bf300f1a419907a9412154760efd0b7abc3/chrome/browser/browsing_instance.cc#55 |
| IN_PROC_BROWSER_TEST_F(ThirdPartyNTPBrowserTest, ProcessPerSite) { |
| GURL base_url = |
| https_test_server().GetURL("ntp.com", "/instant_extended.html"); |
| GURL ntp_url = |
| https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html"); |
| InstantTestBase::Init(base_url, ntp_url, false); |
| SetupInstant(browser()); |
| |
| // Open NTP in |tab1|. |
| content::WebContents* tab1; |
| { |
| content::WebContentsAddedObserver tab1_observer; |
| |
| // Try to simulate as closely as possible what would have happened in the |
| // real user interaction. In particular, do *not* use |
| // local_ntp_test_utils::OpenNewTab, which requires the caller to specify |
| // the URL of the new tab. |
| chrome::NewTab(browser()); |
| |
| // Wait for the new tab. |
| tab1 = tab1_observer.GetWebContents(); |
| ASSERT_TRUE(WaitForLoadStop(tab1)); |
| |
| // Sanity check: the NTP should be provided by |ntp_url| (and not by |
| // chrome-search://local-ntp [1st-party NTP] or chrome://ntp [incognito]). |
| EXPECT_EQ(ntp_url, content::EvalJs(tab1, "window.location.href")); |
| } |
| |
| // Open another NTP in |tab2|. |
| content::WebContents* tab2; |
| { |
| content::WebContentsAddedObserver tab2_observer; |
| chrome::NewTab(browser()); |
| tab2 = tab2_observer.GetWebContents(); |
| ASSERT_TRUE(WaitForLoadStop(tab2)); |
| EXPECT_EQ(ntp_url, content::EvalJs(tab2, "window.location.href")); |
| } |
| |
| // Verify that |tab1| and |tab2| share a process. |
| EXPECT_EQ(tab1->GetMainFrame()->GetProcess(), |
| tab2->GetMainFrame()->GetProcess()); |
| } |