1 // Copyright 2019 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/heavy_ad_intervention/heavy_ad_helper.h"
6 
7 #include "chrome/browser/ui/browser.h"
8 #include "chrome/grit/generated_resources.h"
9 #include "chrome/test/base/in_process_browser_test.h"
10 #include "chrome/test/base/ui_test_utils.h"
11 #include "content/public/browser/navigation_controller.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/site_isolation_policy.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/test/browser_test.h"
16 #include "content/public/test/browser_test_utils.h"
17 #include "content/public/test/test_navigation_observer.h"
18 #include "net/dns/mock_host_resolver.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "url/gurl.h"
22 
23 namespace {
24 
IsContentInDocument(content::RenderFrameHost * rfh,std::string content)25 bool IsContentInDocument(content::RenderFrameHost* rfh, std::string content) {
26   std::string script =
27       "document.documentElement.innerHTML.includes('" + content + "');";
28   // Execute script in an isolated world to avoid causing a Trusted Types
29   // violation due to eval.
30   return EvalJs(rfh, script, content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
31                 /*world_id=*/1)
32       .ExtractBool();
33 }
34 
35 }  // namespace
36 
37 class HeavyAdHelperBrowserTest : public InProcessBrowserTest {
38  public:
HeavyAdHelperBrowserTest()39   HeavyAdHelperBrowserTest() {}
~HeavyAdHelperBrowserTest()40   ~HeavyAdHelperBrowserTest() override {}
41 
SetUpOnMainThread()42   void SetUpOnMainThread() override {
43     host_resolver()->AddRule("*", "127.0.0.1");
44     content::SetupCrossSiteRedirector(embedded_test_server());
45     ASSERT_TRUE(embedded_test_server()->Start());
46   }
47 };
48 
49 // Verifies that there are no JS errors or missing load time data in the error
50 // page for heavy ads.
IN_PROC_BROWSER_TEST_F(HeavyAdHelperBrowserTest,HeavyAdErrorPage_NoConsoleMessages)51 IN_PROC_BROWSER_TEST_F(HeavyAdHelperBrowserTest,
52                        HeavyAdErrorPage_NoConsoleMessages) {
53   content::WebContents* web_contents =
54       browser()->tab_strip_model()->GetActiveWebContents();
55   content::NavigationController& controller = web_contents->GetController();
56 
57   GURL url(embedded_test_server()->GetURL("/iframe.html"));
58   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
59 
60   content::RenderFrameHost* child =
61       ChildFrameAt(web_contents->GetMainFrame(), 0);
62 
63   content::WebContentsConsoleObserver console_observer(web_contents);
64 
65   content::TestNavigationObserver error_observer(web_contents);
66   controller.LoadPostCommitErrorPage(
67       child, url, heavy_ads::PrepareHeavyAdPage(), net::ERR_BLOCKED_BY_CLIENT);
68   error_observer.Wait();
69 
70   EXPECT_TRUE(console_observer.messages().empty());
71 }
72 
73 // Checks that the heavy ad strings are in the html content of the rendered
74 // error page.
IN_PROC_BROWSER_TEST_F(HeavyAdHelperBrowserTest,HeavyAdErrorPage_HeavyAdStringsUsed)75 IN_PROC_BROWSER_TEST_F(HeavyAdHelperBrowserTest,
76                        HeavyAdErrorPage_HeavyAdStringsUsed) {
77   content::WebContents* web_contents =
78       browser()->tab_strip_model()->GetActiveWebContents();
79   content::NavigationController& controller = web_contents->GetController();
80 
81   GURL url(embedded_test_server()->GetURL("/iframe.html"));
82   EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
83 
84   content::RenderFrameHost* child =
85       ChildFrameAt(web_contents->GetMainFrame(), 0);
86 
87   content::TestNavigationObserver error_observer(web_contents);
88   controller.LoadPostCommitErrorPage(
89       child, url, heavy_ads::PrepareHeavyAdPage(), net::ERR_BLOCKED_BY_CLIENT);
90   error_observer.Wait();
91 
92   // With error page isolation, the error page will be loaded in the error
93   // page process, therefore it will have a different RenderFrameHost
94   // instance.
95   if (content::SiteIsolationPolicy::IsErrorPageIsolationEnabled(
96           /* in_main_frame = */ false)) {
97     child = ChildFrameAt(web_contents->GetMainFrame(), 0);
98   }
99 
100   EXPECT_TRUE(IsContentInDocument(
101       child,
102       l10n_util::GetStringUTF8(IDS_HEAVY_AD_INTERVENTION_BUTTON_DETAILS)));
103   EXPECT_TRUE(IsContentInDocument(
104       child, l10n_util::GetStringUTF8(IDS_HEAVY_AD_INTERVENTION_HEADING)));
105   EXPECT_TRUE(IsContentInDocument(
106       child, l10n_util::GetStringUTF8(IDS_HEAVY_AD_INTERVENTION_SUMMARY)));
107 }
108