[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_content_browser_client_browsertest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chrome_content_browser_client.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/macros.h"
13 #include "base/no_destructor.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/test/scoped_feature_list.h"
17 #include "build/build_config.h"
18 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
19 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/search/instant_service.h"
22 #include "chrome/browser/search/instant_service_factory.h"
23 #include "chrome/browser/search/search.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/search/instant_test_base.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/browser/ui/ui_features.h"
28 #include "chrome/common/chrome_features.h"
29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/common/url_constants.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "components/network_session_configurator/common/network_switches.h"
35 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
36 #include "components/prefs/pref_service.h"
37 #include "components/site_isolation/site_isolation_policy.h"
38 #include "content/public/browser/navigation_controller.h"
39 #include "content/public/browser/navigation_entry.h"
40 #include "content/public/browser/render_frame_host.h"
41 #include "content/public/browser/render_process_host.h"
42 #include "content/public/browser/render_view_host.h"
43 #include "content/public/browser/web_contents.h"
44 #include "content/public/common/content_client.h"
45 #include "content/public/common/content_switches.h"
46 #include "content/public/test/browser_test.h"
47 #include "content/public/test/browser_test_utils.h"
48 #include "content/public/test/test_navigation_observer.h"
49 #include "net/dns/mock_host_resolver.h"
50 #include "net/http/http_status_code.h"
51 #include "net/test/embedded_test_server/embedded_test_server.h"
52 #include "net/test/embedded_test_server/http_request.h"
53 #include "net/test/embedded_test_server/http_response.h"
54 #include "ui/native_theme/native_theme.h"
55 #include "ui/native_theme/test_native_theme.h"
56 #include "url/gurl.h"
57 #include "url/origin.h"
58
59 #if BUILDFLAG(ENABLE_EXTENSIONS)
60 #include "extensions/common/constants.h"
61 #include "extensions/common/extension_urls.h"
62 #include "url/url_constants.h"
63 #endif
64
65 #if defined(OS_MACOSX)
66 #include "chrome/test/base/launchservices_utils_mac.h"
67 #endif
68
69 namespace content {
70
71 namespace {
72
73 enum class NetworkServiceState {
74   kDisabled,
75   kEnabled,
76 };
77
78 }  // namespace
79
80 // Use a test class with SetUpCommandLine to ensure the flag is sent to the
81 // first renderer process.
82 class ChromeContentBrowserClientBrowserTest : public InProcessBrowserTest {
83  public:
84   ChromeContentBrowserClientBrowserTest() {}
85
86   void SetUpCommandLine(base::CommandLine* command_line) override {
87     IsolateAllSitesForTesting(command_line);
88   }
89
90  private:
91   DISALLOW_COPY_AND_ASSIGN(ChromeContentBrowserClientBrowserTest);
92 };
93
94 // Test that a basic navigation works in --site-per-process mode.  This prevents
95 // regressions when that mode calls out into the ChromeContentBrowserClient,
96 // such as http://crbug.com/164223.
97 IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientBrowserTest,
98                        SitePerProcessNavigation) {
99   ASSERT_TRUE(embedded_test_server()->Start());
100   const GURL url(embedded_test_server()->GetURL("/title1.html"));
101
102   ui_test_utils::NavigateToURL(browser(), url);
103   NavigationEntry* entry = browser()
104                                ->tab_strip_model()
105                                ->GetWebContentsAt(0)
106                                ->GetController()
107                                .GetLastCommittedEntry();
108
109   ASSERT_TRUE(entry != NULL);
110   EXPECT_EQ(url, entry->GetURL());
111   EXPECT_EQ(url, entry->GetVirtualURL());
112 }
113
114 class ChromeContentBrowserClientPopupsTest : public InProcessBrowserTest {
115  public:
116   void SetUpCommandLine(base::CommandLine* command_line) override {
117     // Required setup for kAllowPopupsDuringPageUnload switch
118     // as its being checked (whether its going to be enabled or not)
119     // only if the process type is renderer process.
120     command_line_.AppendSwitchASCII(switches::kProcessType,
121                                     switches::kRendererProcess);
122   }
123   void SetUpOnMainThread() override {
124     kChildProcessId = browser()
125                           ->tab_strip_model()
126                           ->GetActiveWebContents()
127                           ->GetMainFrame()
128                           ->GetProcess()
129                           ->GetID();
130   }
131   ChromeContentBrowserClientPopupsTest()
132       : command_line_(base::CommandLine::NO_PROGRAM) {}
133
134   void AppendContentBrowserClientSwitches() {
135     client_.AppendExtraCommandLineSwitches(&command_line_, kChildProcessId);
136   }
137
138   const base::CommandLine& command_line() const { return command_line_; }
139
140  private:
141   ChromeContentBrowserClient client_;
142   base::CommandLine command_line_;
143   int kChildProcessId;
144 };
145
146 IN_PROC_BROWSER_TEST_F(ChromeContentBrowserClientPopupsTest,
147                        AllowPopupsDuringPageUnload) {
148   // Verify that the switch is included only when the
149   // pref AllowPopupsDuringPageUnload value is true.
150
151   PrefService* pref_service = browser()->profile()->GetPrefs();
152   pref_service->SetBoolean(prefs::kAllowPopupsDuringPageUnload, false);
153   AppendContentBrowserClientSwitches();
154   EXPECT_FALSE(
155       command_line().HasSwitch(switches::kAllowPopupsDuringPageUnload));
156   // When the pref value is being set to true
157   // the switch should be included.
158   pref_service->SetBoolean(prefs::kAllowPopupsDuringPageUnload, true);
159   AppendContentBrowserClientSwitches();
160   EXPECT_TRUE(command_line().HasSwitch(switches::kAllowPopupsDuringPageUnload));
161 }
162
163 // Helper class to mark "https://ntp.com/" as an isolated origin.
164 class IsolatedOriginNTPBrowserTest : public InProcessBrowserTest,
165                                      public InstantTestBase {
166  public:
167   IsolatedOriginNTPBrowserTest() {}
168
169   void SetUpCommandLine(base::CommandLine* command_line) override {
170     ASSERT_TRUE(https_test_server().InitializeAndListen());
171
172     // Mark ntp.com (with an appropriate port from the test server) as an
173     // isolated origin.
174     GURL isolated_url(https_test_server().GetURL("ntp.com", "/"));
175     command_line->AppendSwitchASCII(switches::kIsolateOrigins,
176                                     isolated_url.spec());
177     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
178   }
179
180   void SetUpOnMainThread() override {
181     InProcessBrowserTest::SetUpOnMainThread();
182     host_resolver()->AddRule("*", "127.0.0.1");
183     https_test_server().StartAcceptingConnections();
184   }
185
186  private:
187   DISALLOW_COPY_AND_ASSIGN(IsolatedOriginNTPBrowserTest);
188 };
189
190 // Verifies that when the remote NTP URL has an origin which is also marked as
191 // an isolated origin (i.e., requiring a dedicated process), the NTP URL
192 // still loads successfully, and the resulting process is marked as an Instant
193 // process.  See https://crbug.com/755595.
194 IN_PROC_BROWSER_TEST_F(IsolatedOriginNTPBrowserTest,
195                        IsolatedOriginDoesNotInterfereWithNTP) {
196   GURL base_url =
197       https_test_server().GetURL("ntp.com", "/instant_extended.html");
198   GURL ntp_url =
199       https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html");
200   InstantTestBase::Init(base_url, ntp_url, false);
201
202   SetupInstant(browser());
203
204   // Sanity check that a SiteInstance for a generic ntp.com URL requires a
205   // dedicated process.
206   content::BrowserContext* context = browser()->profile();
207   GURL isolated_url(https_test_server().GetURL("ntp.com", "/title1.html"));
208   scoped_refptr<SiteInstance> site_instance =
209       SiteInstance::CreateForURL(context, isolated_url);
210   EXPECT_TRUE(site_instance->RequiresDedicatedProcess());
211
212   // The site URL for the NTP URL should resolve to a chrome-search:// URL via
213   // GetEffectiveURL(), even if the NTP URL matches an isolated origin.
214   GURL site_url(content::SiteInstance::GetSiteForURL(context, ntp_url));
215   EXPECT_TRUE(site_url.SchemeIs(chrome::kChromeSearchScheme));
216
217   // Navigate to the NTP URL and verify that the resulting process is marked as
218   // an Instant process.
219   ui_test_utils::NavigateToURL(browser(), ntp_url);
220   content::WebContents* contents =
221       browser()->tab_strip_model()->GetActiveWebContents();
222   InstantService* instant_service =
223       InstantServiceFactory::GetForProfile(browser()->profile());
224   EXPECT_TRUE(instant_service->IsInstantProcess(
225       contents->GetMainFrame()->GetProcess()->GetID()));
226
227   // Navigating to a non-NTP URL on ntp.com should not result in an Instant
228   // process.
229   ui_test_utils::NavigateToURL(browser(), isolated_url);
230   EXPECT_FALSE(instant_service->IsInstantProcess(
231       contents->GetMainFrame()->GetProcess()->GetID()));
232 }
233
234 // Helper class to test window creation from NTP.
235 class OpenWindowFromNTPBrowserTest : public InProcessBrowserTest,
236                                      public InstantTestBase {
237  public:
238   OpenWindowFromNTPBrowserTest() {}
239
240   void SetUpCommandLine(base::CommandLine* command_line) override {
241     command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
242   }
243
244   void SetUpOnMainThread() override {
245     InProcessBrowserTest::SetUpOnMainThread();
246     host_resolver()->AddRule("*", "127.0.0.1");
247     ASSERT_TRUE(https_test_server().InitializeAndListen());
248     https_test_server().StartAcceptingConnections();
249   }
250
251  private:
252   DISALLOW_COPY_AND_ASSIGN(OpenWindowFromNTPBrowserTest);
253 };
254
255 // Test checks that navigations from NTP tab to URLs with same host as NTP but
256 // different path do not reuse NTP SiteInstance. See https://crbug.com/859062
257 // for details.
258 IN_PROC_BROWSER_TEST_F(OpenWindowFromNTPBrowserTest,
259                        TransferFromNTPCreateNewTab) {
260   GURL search_url =
261       https_test_server().GetURL("ntp.com", "/instant_extended.html");
262   GURL ntp_url =
263       https_test_server().GetURL("ntp.com", "/instant_extended_ntp.html");
264   InstantTestBase::Init(search_url, ntp_url, false);
265
266   SetupInstant(browser());
267
268   // Navigate to the NTP URL and verify that the resulting process is marked as
269   // an Instant process.
270   ui_test_utils::NavigateToURL(browser(), ntp_url);
271   content::WebContents* ntp_tab =
272       browser()->tab_strip_model()->GetActiveWebContents();
273   InstantService* instant_service =
274       InstantServiceFactory::GetForProfile(browser()->profile());
275   EXPECT_TRUE(instant_service->IsInstantProcess(
276       ntp_tab->GetMainFrame()->GetProcess()->GetID()));
277
278   // Execute script that creates new window from ntp tab with
279   // ntp.com/title1.html as target url. Host is same as remote-ntp host, yet
280   // path is different.
281   GURL generic_url(https_test_server().GetURL("ntp.com", "/title1.html"));
282   content::TestNavigationObserver opened_tab_observer(nullptr);
283   opened_tab_observer.StartWatchingNewWebContents();
284   EXPECT_TRUE(
285       ExecuteScript(ntp_tab, "window.open('" + generic_url.spec() + "');"));
286   opened_tab_observer.Wait();
287   ASSERT_EQ(2, browser()->tab_strip_model()->count());
288
289   content::WebContents* opened_tab =
290       browser()->tab_strip_model()->GetActiveWebContents();
291
292   // Wait until newly opened tab is fully loaded.
293   EXPECT_TRUE(WaitForLoadStop(opened_tab));
294
295   EXPECT_NE(opened_tab, ntp_tab);
296   EXPECT_EQ(generic_url, opened_tab->GetLastCommittedURL());
297   // New created tab should not reside in an Instant process.
298   EXPECT_FALSE(instant_service->IsInstantProcess(
299       opened_tab->GetMainFrame()->GetProcess()->GetID()));
300 }
301
302 class PrefersColorSchemeTest : public testing::WithParamInterface<bool>,
303                                public InProcessBrowserTest {
304  protected:
305   PrefersColorSchemeTest() : theme_client_(&test_theme_) {
306     feature_list_.InitWithFeatureState(features::kWebUIDarkMode, GetParam());
307   }
308
309   ~PrefersColorSchemeTest() override {
310     CHECK_EQ(&theme_client_, SetBrowserClientForTesting(original_client_));
311   }
312
313   const char* ExpectedColorScheme() const {
314     return GetParam() ? "dark" : "light";
315   }
316
317   void SetUpCommandLine(base::CommandLine* command_line) override {
318     InProcessBrowserTest::SetUpCommandLine(command_line);
319     command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
320                                     "MediaQueryPrefersColorScheme");
321   }
322
323   void SetUpOnMainThread() override {
324     InProcessBrowserTest::SetUpOnMainThread();
325     original_client_ = SetBrowserClientForTesting(&theme_client_);
326   }
327
328  protected:
329   ui::TestNativeTheme test_theme_;
330
331  private:
332   content::ContentBrowserClient* original_client_ = nullptr;
333
334   class ChromeContentBrowserClientWithWebTheme
335       : public ChromeContentBrowserClient {
336    public:
337     explicit ChromeContentBrowserClientWithWebTheme(
338         const ui::NativeTheme* theme)
339         : theme_(theme) {}
340
341    protected:
342     const ui::NativeTheme* GetWebTheme() const override { return theme_; }
343
344    private:
345     const ui::NativeTheme* const theme_;
346   };
347
348   base::test::ScopedFeatureList feature_list_;
349   ChromeContentBrowserClientWithWebTheme theme_client_;
350 };
351
352 IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, PrefersColorScheme) {
353   test_theme_.SetDarkMode(GetParam());
354   browser()
355       ->tab_strip_model()
356       ->GetActiveWebContents()
357       ->GetRenderViewHost()
358       ->OnWebkitPreferencesChanged();
359   ui_test_utils::NavigateToURL(
360       browser(),
361       ui_test_utils::GetTestUrl(
362           base::FilePath(base::FilePath::kCurrentDirectory),
363           base::FilePath(FILE_PATH_LITERAL("prefers-color-scheme.html"))));
364   base::string16 tab_title;
365   ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
366   EXPECT_EQ(base::ASCIIToUTF16(ExpectedColorScheme()), tab_title);
367 }
368
369 IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, FeatureOverridesChromeSchemes) {
370   test_theme_.SetDarkMode(true);
371
372   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIDownloadsURL));
373
374   bool matches;
375   ASSERT_TRUE(ExecuteScriptAndExtractBool(
376       browser()->tab_strip_model()->GetActiveWebContents(),
377       base::StringPrintf("window.domAutomationController.send(window."
378                          "matchMedia('(prefers-color-scheme: %s)').matches)",
379                          ExpectedColorScheme()),
380       &matches));
381   EXPECT_TRUE(matches);
382 }
383
384 #if BUILDFLAG(ENABLE_EXTENSIONS)
385 IN_PROC_BROWSER_TEST_P(PrefersColorSchemeTest, FeatureOverridesPdfUI) {
386   test_theme_.SetDarkMode(true);
387
388   std::string pdf_extension_url(extensions::kExtensionScheme);
389   pdf_extension_url.append(url::kStandardSchemeSeparator);
390   pdf_extension_url.append(extension_misc::kPdfExtensionId);
391   GURL pdf_index = GURL(pdf_extension_url).Resolve("/index.html");
392   ui_test_utils::NavigateToURL(browser(), pdf_index);
393
394   bool matches;
395   ASSERT_TRUE(ExecuteScriptAndExtractBool(
396       browser()->tab_strip_model()->GetActiveWebContents(),
397       base::StringPrintf("window.domAutomationController.send(window."
398                          "matchMedia('(prefers-color-scheme: %s)').matches)",
399                          ExpectedColorScheme()),
400       &matches));
401   EXPECT_TRUE(matches);
402 }
403 #endif
404
405 INSTANTIATE_TEST_SUITE_P(All, PrefersColorSchemeTest, testing::Bool());
406
407 class ProtocolHandlerTest : public InProcessBrowserTest {
408  public:
409   ProtocolHandlerTest() = default;
410
411   void SetUpOnMainThread() override {
412     InProcessBrowserTest::SetUpOnMainThread();
413     host_resolver()->AddRule("*", "127.0.0.1");
414     ASSERT_TRUE(embedded_test_server()->Start());
415   }
416
417  protected:
418   void AddProtocolHandler(const std::string& scheme,
419                           const std::string& redirect_template) {
420     protocol_handler_registry()->OnAcceptRegisterProtocolHandler(
421         ProtocolHandler::CreateProtocolHandler(scheme,
422                                                GURL(redirect_template)));
423   }
424
425   ProtocolHandlerRegistry* protocol_handler_registry() {
426     return ProtocolHandlerRegistryFactory::GetInstance()->GetForBrowserContext(
427         browser()->profile());
428   }
429
430  private:
431   DISALLOW_COPY_AND_ASSIGN(ProtocolHandlerTest);
432 };
433
434 IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, CustomHandler) {
435 #if defined(OS_MACOSX)
436   ASSERT_TRUE(test::RegisterAppWithLaunchServices());
437 #endif
438   AddProtocolHandler("news", "https://abc.xyz/?url=%s");
439
440   ui_test_utils::NavigateToURL(browser(), GURL("news:something"));
441
442   base::string16 expected_title = base::ASCIIToUTF16("abc.xyz");
443   content::TitleWatcher title_watcher(
444       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
445   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
446 }
447
448 // This is a regression test for crbug.com/969177.
449 IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, HandlersIgnoredWhenDisabled) {
450   AddProtocolHandler("bitcoin", "https://abc.xyz/?url=%s");
451   protocol_handler_registry()->Disable();
452
453   ui_test_utils::NavigateToURL(browser(), GURL("bitcoin:something"));
454
455   base::string16 tab_title;
456   ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title));
457   EXPECT_EQ(base::ASCIIToUTF16("about:blank"), tab_title);
458 }
459
460 #if defined(OS_CHROMEOS)
461 // Tests that if a protocol handler is registered for a scheme, an external
462 // program (another Chrome tab in this case) is not launched to handle the
463 // navigation. This is a regression test for crbug.com/963133.
464 IN_PROC_BROWSER_TEST_F(ProtocolHandlerTest, ExternalProgramNotLaunched) {
465   ui_test_utils::NavigateToURL(browser(), GURL("mailto:bob@example.com"));
466
467   // If an external program (Chrome) was launched, it will result in a second
468   // tab being opened.
469   EXPECT_EQ(1, browser()->tab_strip_model()->count());
470
471   // Make sure the protocol handler redirected the navigation.
472   base::string16 expected_title = base::ASCIIToUTF16("mail.google.com");
473   content::TitleWatcher title_watcher(
474       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
475   EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
476 }
477 #endif
478
479 }  // namespace content