• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // This test creates a fake safebrowsing service, where we can inject
6 // malware and phishing urls.  It then uses a real browser to go to
7 // these urls, and sends "goback" or "proceed" commands and verifies
8 // they work.
9 
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/safe_browsing/database_manager.h"
18 #include "chrome/browser/safe_browsing/malware_details.h"
19 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
20 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
22 #include "chrome/browser/safe_browsing/ui_manager.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_tabstrip.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/common/pref_names.h"
27 #include "chrome/common/url_constants.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/test_switches.h"
30 #include "chrome/test/base/ui_test_utils.h"
31 #include "content/public/browser/interstitial_page.h"
32 #include "content/public/browser/navigation_controller.h"
33 #include "content/public/browser/notification_types.h"
34 #include "content/public/browser/render_frame_host.h"
35 #include "content/public/browser/render_view_host.h"
36 #include "content/public/browser/web_contents.h"
37 #include "content/public/test/test_browser_thread.h"
38 #include "content/public/test/test_utils.h"
39 
40 using content::BrowserThread;
41 using content::InterstitialPage;
42 using content::NavigationController;
43 using content::WebContents;
44 
45 namespace {
46 
47 const char kEmptyPage[] = "files/empty.html";
48 const char kMalwarePage[] = "files/safe_browsing/malware.html";
49 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
50 
51 class InterstitialObserver : public content::WebContentsObserver {
52  public:
InterstitialObserver(content::WebContents * web_contents,const base::Closure & attach_callback,const base::Closure & detach_callback)53   InterstitialObserver(content::WebContents* web_contents,
54                        const base::Closure& attach_callback,
55                        const base::Closure& detach_callback)
56       : WebContentsObserver(web_contents),
57         attach_callback_(attach_callback),
58         detach_callback_(detach_callback) {
59   }
60 
DidAttachInterstitialPage()61   virtual void DidAttachInterstitialPage() OVERRIDE {
62     LOG(INFO) << __FUNCTION__;
63     attach_callback_.Run();
64   }
65 
DidDetachInterstitialPage()66   virtual void DidDetachInterstitialPage() OVERRIDE {
67     LOG(INFO) << __FUNCTION__;
68     detach_callback_.Run();
69   }
70 
71  private:
72   base::Closure attach_callback_;
73   base::Closure detach_callback_;
74 
75   DISALLOW_COPY_AND_ASSIGN(InterstitialObserver);
76 };
77 
78 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious
79 // URLs.
80 class FakeSafeBrowsingDatabaseManager :  public SafeBrowsingDatabaseManager {
81  public:
FakeSafeBrowsingDatabaseManager(SafeBrowsingService * service)82   explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
83       : SafeBrowsingDatabaseManager(service) { }
84 
85   // Called on the IO thread to check if the given url is safe or not.  If we
86   // can synchronously determine that the url is safe, CheckUrl returns true.
87   // Otherwise it returns false, and "client" is called asynchronously with the
88   // result when it is ready.
89   // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
CheckBrowseUrl(const GURL & gurl,Client * client)90   virtual bool CheckBrowseUrl(const GURL& gurl, Client* client) OVERRIDE {
91     if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE)
92       return true;
93 
94     BrowserThread::PostTask(
95         BrowserThread::IO, FROM_HERE,
96         base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
97                    this, gurl, client));
98     return false;
99   }
100 
OnCheckBrowseURLDone(const GURL & gurl,Client * client)101   void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
102     std::vector<SBThreatType> expected_threats;
103     expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
104     expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
105     SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
106         std::vector<GURL>(1, gurl),
107         std::vector<SBFullHash>(),
108         client,
109         safe_browsing_util::MALWARE,
110         expected_threats);
111     sb_check.url_results[0] = badurls[gurl.spec()];
112     client->OnSafeBrowsingResult(sb_check);
113   }
114 
SetURLThreatType(const GURL & url,SBThreatType threat_type)115   void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
116     badurls[url.spec()] = threat_type;
117   }
118 
119  private:
~FakeSafeBrowsingDatabaseManager()120   virtual ~FakeSafeBrowsingDatabaseManager() {}
121 
122   base::hash_map<std::string, SBThreatType> badurls;
123   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
124 };
125 
126 // A SafeBrowingUIManager class that allows intercepting malware details.
127 class FakeSafeBrowsingUIManager :  public SafeBrowsingUIManager {
128  public:
FakeSafeBrowsingUIManager(SafeBrowsingService * service)129   explicit FakeSafeBrowsingUIManager(SafeBrowsingService* service) :
130       SafeBrowsingUIManager(service) { }
131 
132   // Overrides SafeBrowsingUIManager
SendSerializedMalwareDetails(const std::string & serialized)133   virtual void SendSerializedMalwareDetails(
134       const std::string& serialized) OVERRIDE {
135     // Notify the UI thread that we got a report.
136     BrowserThread::PostTask(
137         BrowserThread::UI,
138         FROM_HERE,
139         base::Bind(&FakeSafeBrowsingUIManager::OnMalwareDetailsDone,
140                    this,
141                    serialized));
142   }
143 
OnMalwareDetailsDone(const std::string & serialized)144   void OnMalwareDetailsDone(const std::string& serialized) {
145     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
146     report_ = serialized;
147 
148     EXPECT_FALSE(malware_details_done_callback_.is_null());
149     if (!malware_details_done_callback_.is_null()) {
150       malware_details_done_callback_.Run();
151       malware_details_done_callback_ = base::Closure();
152     }
153   }
154 
set_malware_details_done_callback(const base::Closure & callback)155   void set_malware_details_done_callback(const base::Closure& callback) {
156     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
157     EXPECT_TRUE(malware_details_done_callback_.is_null());
158     malware_details_done_callback_ = callback;
159   }
160 
GetReport()161   std::string GetReport() {
162     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
163     return report_;
164   }
165 
166  protected:
~FakeSafeBrowsingUIManager()167   virtual ~FakeSafeBrowsingUIManager() { }
168 
169  private:
170   std::string report_;
171   base::Closure malware_details_done_callback_;
172 
173   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager);
174 };
175 
176 class FakeSafeBrowsingService : public SafeBrowsingService {
177  public:
FakeSafeBrowsingService()178   FakeSafeBrowsingService()
179       : fake_database_manager_(),
180         fake_ui_manager_() { }
181 
182   // Returned pointer has the same lifespan as the database_manager_ refcounted
183   // object.
fake_database_manager()184   FakeSafeBrowsingDatabaseManager* fake_database_manager() {
185     return fake_database_manager_;
186   }
187   // Returned pointer has the same lifespan as the ui_manager_ refcounted
188   // object.
fake_ui_manager()189   FakeSafeBrowsingUIManager* fake_ui_manager() {
190     return fake_ui_manager_;
191   }
192 
193  protected:
~FakeSafeBrowsingService()194   virtual ~FakeSafeBrowsingService() { }
195 
CreateDatabaseManager()196   virtual SafeBrowsingDatabaseManager* CreateDatabaseManager() OVERRIDE {
197     fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
198     return fake_database_manager_;
199   }
200 
CreateUIManager()201   virtual SafeBrowsingUIManager* CreateUIManager() OVERRIDE {
202     fake_ui_manager_ = new FakeSafeBrowsingUIManager(this);
203     return fake_ui_manager_;
204   }
205 
206  private:
207   FakeSafeBrowsingDatabaseManager* fake_database_manager_;
208   FakeSafeBrowsingUIManager* fake_ui_manager_;
209 
210   DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
211 };
212 
213 // Factory that creates FakeSafeBrowsingService instances.
214 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
215  public:
TestSafeBrowsingServiceFactory()216   TestSafeBrowsingServiceFactory() :
217       most_recent_service_(NULL) { }
~TestSafeBrowsingServiceFactory()218   virtual ~TestSafeBrowsingServiceFactory() { }
219 
CreateSafeBrowsingService()220   virtual SafeBrowsingService* CreateSafeBrowsingService() OVERRIDE {
221     most_recent_service_ =  new FakeSafeBrowsingService();
222     return most_recent_service_;
223   }
224 
most_recent_service() const225   FakeSafeBrowsingService* most_recent_service() const {
226     return most_recent_service_;
227   }
228 
229  private:
230   FakeSafeBrowsingService* most_recent_service_;
231 };
232 
233 // A MalwareDetails class lets us intercept calls from the renderer.
234 class FakeMalwareDetails : public MalwareDetails {
235  public:
FakeMalwareDetails(SafeBrowsingUIManager * delegate,WebContents * web_contents,const SafeBrowsingUIManager::UnsafeResource & unsafe_resource)236   FakeMalwareDetails(
237       SafeBrowsingUIManager* delegate,
238       WebContents* web_contents,
239       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource)
240       : MalwareDetails(delegate, web_contents, unsafe_resource),
241         got_dom_(false),
242         waiting_(false) { }
243 
AddDOMDetails(const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node> & params)244   virtual void AddDOMDetails(
245       const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params)
246           OVERRIDE {
247     EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
248     MalwareDetails::AddDOMDetails(params);
249 
250     // Notify the UI thread that we got the dom details.
251     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
252                             base::Bind(&FakeMalwareDetails::OnDOMDetailsDone,
253                                        this));
254   }
255 
WaitForDOM()256   void WaitForDOM() {
257     if (got_dom_) {
258       LOG(INFO) << "Already got the dom details.";
259       return;
260     }
261     // This condition might not trigger normally, but if you add a
262     // sleep(1) in malware_dom_details it triggers :).
263     waiting_ = true;
264     LOG(INFO) << "Waiting for dom details.";
265     content::RunMessageLoop();
266     EXPECT_TRUE(got_dom_);
267   }
268 
269  private:
~FakeMalwareDetails()270   virtual ~FakeMalwareDetails() {}
271 
OnDOMDetailsDone()272   void OnDOMDetailsDone() {
273     got_dom_ = true;
274     if (waiting_) {
275       base::MessageLoopForUI::current()->Quit();
276     }
277   }
278 
279   // Some logic to figure out if we should wait for the dom details or not.
280   // These variables should only be accessed in the UI thread.
281   bool got_dom_;
282   bool waiting_;
283 };
284 
285 class TestMalwareDetailsFactory : public MalwareDetailsFactory {
286  public:
TestMalwareDetailsFactory()287   TestMalwareDetailsFactory() : details_() { }
~TestMalwareDetailsFactory()288   virtual ~TestMalwareDetailsFactory() { }
289 
CreateMalwareDetails(SafeBrowsingUIManager * delegate,WebContents * web_contents,const SafeBrowsingUIManager::UnsafeResource & unsafe_resource)290   virtual MalwareDetails* CreateMalwareDetails(
291       SafeBrowsingUIManager* delegate,
292       WebContents* web_contents,
293       const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) OVERRIDE {
294     details_ = new FakeMalwareDetails(delegate, web_contents,
295                                       unsafe_resource);
296     return details_;
297   }
298 
get_details()299   FakeMalwareDetails* get_details() {
300     return details_;
301   }
302 
303  private:
304   FakeMalwareDetails* details_;
305 };
306 
307 // A SafeBrowingBlockingPage class that lets us wait until it's hidden.
308 class TestSafeBrowsingBlockingPageV2 : public SafeBrowsingBlockingPageV2 {
309  public:
TestSafeBrowsingBlockingPageV2(SafeBrowsingUIManager * manager,WebContents * web_contents,const UnsafeResourceList & unsafe_resources)310   TestSafeBrowsingBlockingPageV2(SafeBrowsingUIManager* manager,
311                                  WebContents* web_contents,
312                                  const UnsafeResourceList& unsafe_resources)
313       : SafeBrowsingBlockingPageV2(manager, web_contents, unsafe_resources),
314         wait_for_delete_(false) {
315     // Don't wait the whole 3 seconds for the browser test.
316     malware_details_proceed_delay_ms_ = 100;
317   }
318 
~TestSafeBrowsingBlockingPageV2()319   virtual ~TestSafeBrowsingBlockingPageV2() {
320     LOG(INFO) << __FUNCTION__;
321     if (!wait_for_delete_)
322       return;
323 
324     // Notify that we are gone
325     base::MessageLoopForUI::current()->Quit();
326     wait_for_delete_ = false;
327   }
328 
WaitForDelete()329   void WaitForDelete() {
330     LOG(INFO) << __FUNCTION__;
331     wait_for_delete_ = true;
332     content::RunMessageLoop();
333   }
334 
335   // InterstitialPageDelegate methods:
CommandReceived(const std::string & command)336   virtual void CommandReceived(const std::string& command) OVERRIDE {
337     LOG(INFO) << __FUNCTION__ << " " << command;
338     SafeBrowsingBlockingPageV2::CommandReceived(command);
339   }
OnProceed()340   virtual void OnProceed() OVERRIDE {
341     LOG(INFO) << __FUNCTION__;
342     SafeBrowsingBlockingPageV2::OnProceed();
343   }
OnDontProceed()344   virtual void OnDontProceed() OVERRIDE {
345     LOG(INFO) << __FUNCTION__;
346     SafeBrowsingBlockingPageV2::OnDontProceed();
347   }
348 
349  private:
350   bool wait_for_delete_;
351 };
352 
353 // A SafeBrowingBlockingPage class that lets us wait until it's hidden.
354 class TestSafeBrowsingBlockingPageV3 : public SafeBrowsingBlockingPageV3 {
355  public:
TestSafeBrowsingBlockingPageV3(SafeBrowsingUIManager * manager,WebContents * web_contents,const UnsafeResourceList & unsafe_resources)356   TestSafeBrowsingBlockingPageV3(SafeBrowsingUIManager* manager,
357                                  WebContents* web_contents,
358                                  const UnsafeResourceList& unsafe_resources)
359       : SafeBrowsingBlockingPageV3(manager, web_contents, unsafe_resources),
360         wait_for_delete_(false) {
361     // Don't wait the whole 3 seconds for the browser test.
362     malware_details_proceed_delay_ms_ = 100;
363   }
364 
~TestSafeBrowsingBlockingPageV3()365   virtual ~TestSafeBrowsingBlockingPageV3() {
366     LOG(INFO) << __FUNCTION__;
367     if (!wait_for_delete_)
368       return;
369 
370     // Notify that we are gone
371     base::MessageLoopForUI::current()->Quit();
372     wait_for_delete_ = false;
373   }
374 
WaitForDelete()375   void WaitForDelete() {
376     LOG(INFO) << __FUNCTION__;
377     wait_for_delete_ = true;
378     content::RunMessageLoop();
379   }
380 
381   // InterstitialPageDelegate methods:
CommandReceived(const std::string & command)382   virtual void CommandReceived(const std::string& command) OVERRIDE {
383     LOG(INFO) << __FUNCTION__ << " " << command;
384     SafeBrowsingBlockingPageV3::CommandReceived(command);
385   }
OnProceed()386   virtual void OnProceed() OVERRIDE {
387     LOG(INFO) << __FUNCTION__;
388     SafeBrowsingBlockingPageV3::OnProceed();
389   }
OnDontProceed()390   virtual void OnDontProceed() OVERRIDE {
391     LOG(INFO) << __FUNCTION__;
392     SafeBrowsingBlockingPageV3::OnDontProceed();
393   }
394 
395  private:
396   bool wait_for_delete_;
397 };
398 
399 class TestSafeBrowsingBlockingPageFactory
400     : public SafeBrowsingBlockingPageFactory {
401  public:
TestSafeBrowsingBlockingPageFactory()402   TestSafeBrowsingBlockingPageFactory() : version_(2) { }
~TestSafeBrowsingBlockingPageFactory()403   virtual ~TestSafeBrowsingBlockingPageFactory() { }
404 
CreateSafeBrowsingPage(SafeBrowsingUIManager * delegate,WebContents * web_contents,const SafeBrowsingBlockingPage::UnsafeResourceList & unsafe_resources)405   virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
406       SafeBrowsingUIManager* delegate,
407       WebContents* web_contents,
408       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
409           OVERRIDE {
410     if (version_ == 3) {
411       return new TestSafeBrowsingBlockingPageV3(delegate, web_contents,
412                                                 unsafe_resources);
413     }
414     return new TestSafeBrowsingBlockingPageV2(delegate, web_contents,
415                                               unsafe_resources);
416   }
417 
SetTestVersion(int version)418   void SetTestVersion(int version) {
419     version_ = version;
420   }
421 
422  private:
423   int version_;
424 };
425 
426 }  // namespace
427 
428 // Tests the safe browsing blocking page in a browser.
429 class SafeBrowsingBlockingPageBrowserTest
430     : public InProcessBrowserTest,
431       public testing::WithParamInterface<int> {
432  public:
433   enum Visibility {
434     VISIBILITY_ERROR = -1,
435     HIDDEN = 0,
436     VISIBLE = 1
437   };
438 
SafeBrowsingBlockingPageBrowserTest()439   SafeBrowsingBlockingPageBrowserTest() {
440   }
441 
SetUp()442   virtual void SetUp() OVERRIDE {
443     SafeBrowsingService::RegisterFactory(&factory_);
444     SafeBrowsingBlockingPage::RegisterFactory(&blocking_page_factory_);
445     blocking_page_factory_.SetTestVersion(GetParam());
446     MalwareDetails::RegisterFactory(&details_factory_);
447     InProcessBrowserTest::SetUp();
448   }
449 
TearDown()450   virtual void TearDown() OVERRIDE {
451     InProcessBrowserTest::TearDown();
452     SafeBrowsingBlockingPage::RegisterFactory(NULL);
453     SafeBrowsingService::RegisterFactory(NULL);
454     MalwareDetails::RegisterFactory(NULL);
455   }
456 
SetUpInProcessBrowserTestFixture()457   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
458     ASSERT_TRUE(test_server()->Start());
459   }
460 
SetURLThreatType(const GURL & url,SBThreatType threat_type)461   void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
462     FakeSafeBrowsingService* service =
463         static_cast<FakeSafeBrowsingService*>(
464             g_browser_process->safe_browsing_service());
465 
466     ASSERT_TRUE(service);
467     service->fake_database_manager()->SetURLThreatType(url, threat_type);
468   }
469 
470   // Adds a safebrowsing result of type |threat_type| to the fake safebrowsing
471   // service, navigates to that page, and returns the url.
SetupWarningAndNavigate(SBThreatType threat_type)472   GURL SetupWarningAndNavigate(SBThreatType threat_type) {
473     GURL url = test_server()->GetURL(kEmptyPage);
474     SetURLThreatType(url, threat_type);
475 
476     ui_test_utils::NavigateToURL(browser(), url);
477     EXPECT_TRUE(WaitForReady());
478     return url;
479   }
480 
481   // Adds a safebrowsing malware result to the fake safebrowsing service,
482   // navigates to a page with an iframe containing the malware site, and
483   // returns the url of the parent page.
SetupMalwareIframeWarningAndNavigate()484   GURL SetupMalwareIframeWarningAndNavigate() {
485     GURL url = test_server()->GetURL(kMalwarePage);
486     GURL iframe_url = test_server()->GetURL(kMalwareIframe);
487     SetURLThreatType(iframe_url, SB_THREAT_TYPE_URL_MALWARE);
488 
489     LOG(INFO) << "navigating... " << url.spec();
490     ui_test_utils::NavigateToURL(browser(), url);
491     EXPECT_TRUE(WaitForReady());
492     return url;
493   }
494 
SendCommand(const std::string & command)495   void SendCommand(const std::string& command) {
496     WebContents* contents =
497         browser()->tab_strip_model()->GetActiveWebContents();
498     // We use InterstitialPage::GetInterstitialPage(tab) instead of
499     // tab->GetInterstitialPage() because the tab doesn't have a pointer
500     // to its interstital page until it gets a command from the renderer
501     // that it has indeed displayed it -- and this sometimes happens after
502     // NavigateToURL returns.
503     SafeBrowsingBlockingPage* interstitial_page =
504         static_cast<SafeBrowsingBlockingPage*>(
505             InterstitialPage::GetInterstitialPage(contents)->
506                 GetDelegateForTesting());
507     ASSERT_TRUE(interstitial_page);
508     interstitial_page->CommandReceived(command);
509   }
510 
DontProceedThroughInterstitial()511   void DontProceedThroughInterstitial() {
512     WebContents* contents =
513         browser()->tab_strip_model()->GetActiveWebContents();
514     InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
515         contents);
516     ASSERT_TRUE(interstitial_page);
517     interstitial_page->DontProceed();
518   }
519 
ProceedThroughInterstitial()520   void ProceedThroughInterstitial() {
521     WebContents* contents =
522         browser()->tab_strip_model()->GetActiveWebContents();
523     InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
524         contents);
525     ASSERT_TRUE(interstitial_page);
526     interstitial_page->Proceed();
527   }
528 
AssertNoInterstitial(bool wait_for_delete)529   void AssertNoInterstitial(bool wait_for_delete) {
530     WebContents* contents =
531         browser()->tab_strip_model()->GetActiveWebContents();
532 
533     if (contents->ShowingInterstitialPage() && wait_for_delete) {
534       // We'll get notified when the interstitial is deleted.
535       if (GetParam() == 3) {
536         TestSafeBrowsingBlockingPageV3* page =
537             static_cast<TestSafeBrowsingBlockingPageV3*>(
538                 contents->GetInterstitialPage()->GetDelegateForTesting());
539         page->WaitForDelete();
540       } else {
541         TestSafeBrowsingBlockingPageV2* page =
542             static_cast<TestSafeBrowsingBlockingPageV2*>(
543                 contents->GetInterstitialPage()->GetDelegateForTesting());
544         page->WaitForDelete();
545       }
546     }
547 
548     // Can't use InterstitialPage::GetInterstitialPage() because that
549     // gets updated after the TestSafeBrowsingBlockingPage destructor
550     ASSERT_FALSE(contents->ShowingInterstitialPage());
551   }
552 
YesInterstitial()553   bool YesInterstitial() {
554     WebContents* contents =
555         browser()->tab_strip_model()->GetActiveWebContents();
556     InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
557         contents);
558     return interstitial_page != NULL;
559   }
560 
WaitForInterstitial()561   void WaitForInterstitial() {
562     WebContents* contents =
563         browser()->tab_strip_model()->GetActiveWebContents();
564     scoped_refptr<content::MessageLoopRunner> loop_runner(
565         new content::MessageLoopRunner);
566     InterstitialObserver observer(contents,
567                                   loop_runner->QuitClosure(),
568                                   base::Closure());
569     if (!InterstitialPage::GetInterstitialPage(contents))
570       loop_runner->Run();
571   }
572 
SetReportSentCallback(const base::Closure & callback)573   void SetReportSentCallback(const base::Closure& callback) {
574     LOG(INFO) << __FUNCTION__;
575     factory_.most_recent_service()
576         ->fake_ui_manager()
577         ->set_malware_details_done_callback(callback);
578   }
579 
GetReportSent()580   std::string GetReportSent() {
581     LOG(INFO) << __FUNCTION__;
582     return factory_.most_recent_service()->fake_ui_manager()->GetReport();
583   }
584 
MalwareRedirectCancelAndProceed(const std::string & open_function)585   void MalwareRedirectCancelAndProceed(const std::string& open_function) {
586     GURL load_url = test_server()->GetURL(
587         "files/safe_browsing/interstitial_cancel.html");
588     GURL malware_url("http://localhost/files/safe_browsing/malware.html");
589     SetURLThreatType(malware_url, SB_THREAT_TYPE_URL_MALWARE);
590 
591     // Load the test page.
592     ui_test_utils::NavigateToURL(browser(), load_url);
593     // Trigger the safe browsing interstitial page via a redirect in
594     // "openWin()".
595     ui_test_utils::NavigateToURLWithDisposition(
596         browser(),
597         GURL("javascript:" + open_function + "()"),
598         CURRENT_TAB,
599         ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
600     WaitForInterstitial();
601     // Cancel the redirect request while interstitial page is open.
602     browser()->tab_strip_model()->ActivateTabAt(0, true);
603     ui_test_utils::NavigateToURLWithDisposition(
604         browser(),
605         GURL("javascript:stopWin()"),
606         CURRENT_TAB,
607         ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
608     browser()->tab_strip_model()->ActivateTabAt(1, true);
609     // Simulate the user clicking "proceed", there should be no crash.  Since
610     // clicking proceed may do nothing (see comment in MalwareRedirectCanceled
611     // below, and crbug.com/76460), we use SendCommand to trigger the callback
612     // directly rather than using ClickAndWaitForDetach since there might not
613     // be a notification to wait for.
614     SendCommand("\"proceed\"");
615   }
616 
GetRenderViewHost()617   content::RenderViewHost* GetRenderViewHost() {
618     InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
619         browser()->tab_strip_model()->GetActiveWebContents());
620     if (!interstitial)
621       return NULL;
622     return interstitial->GetRenderViewHostForTesting();
623   }
624 
WaitForReady()625   bool WaitForReady() {
626     LOG(INFO) << __FUNCTION__;
627     content::RenderViewHost* rvh = GetRenderViewHost();
628     if (!rvh)
629       return false;
630     // Wait until all <script> tags have executed, including jstemplate.
631     // TODO(joaodasilva): it would be nice to avoid the busy loop, though in
632     // practice it spins at most once or twice.
633     std::string ready_state;
634     do {
635       scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
636           rvh->GetMainFrame(), "document.readyState");
637       if (!value.get() || !value->GetAsString(&ready_state))
638         return false;
639     } while (ready_state != "complete");
640     LOG(INFO) << "done waiting";
641     return true;
642   }
643 
GetVisibility(const std::string & node_id)644   Visibility GetVisibility(const std::string& node_id) {
645     content::RenderViewHost* rvh = GetRenderViewHost();
646     if (!rvh)
647       return VISIBILITY_ERROR;
648     scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
649         rvh->GetMainFrame(),
650         "var node = document.getElementById('" + node_id + "');\n"
651         "if (node)\n"
652         "   node.offsetWidth > 0 && node.offsetHeight > 0;"
653         "else\n"
654         "  'node not found';\n");
655     if (!value.get())
656       return VISIBILITY_ERROR;
657     bool result = false;
658     if (!value->GetAsBoolean(&result))
659       return VISIBILITY_ERROR;
660     return result ? VISIBLE : HIDDEN;
661   }
662 
Click(const std::string & node_id)663   bool Click(const std::string& node_id) {
664     LOG(INFO) << "Click " << node_id;
665     content::RenderViewHost* rvh = GetRenderViewHost();
666     if (!rvh)
667       return false;
668     // We don't use ExecuteScriptAndGetValue for this one, since clicking
669     // the button/link may navigate away before the injected javascript can
670     // reply, hanging the test.
671     rvh->GetMainFrame()->ExecuteJavaScript(
672         base::ASCIIToUTF16(
673             "document.getElementById('" + node_id + "').click();\n"));
674     return true;
675   }
676 
ClickAndWaitForDetach(const std::string & node_id)677   bool ClickAndWaitForDetach(const std::string& node_id) {
678     // We wait for interstitial_detached rather than nav_entry_committed, as
679     // going back from a main-frame malware interstitial page will not cause a
680     // nav entry committed event.
681     scoped_refptr<content::MessageLoopRunner> loop_runner(
682         new content::MessageLoopRunner);
683     InterstitialObserver observer(
684         browser()->tab_strip_model()->GetActiveWebContents(),
685         base::Closure(),
686         loop_runner->QuitClosure());
687     if (!Click(node_id))
688       return false;
689     loop_runner->Run();
690     return true;
691   }
692 
693  protected:
694   TestMalwareDetailsFactory details_factory_;
695 
696  private:
697   TestSafeBrowsingServiceFactory factory_;
698   TestSafeBrowsingBlockingPageFactory blocking_page_factory_;
699 
700   DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageBrowserTest);
701 };
702 
703 INSTANTIATE_TEST_CASE_P(SafeBrowsingInterstitialVersions,
704                         SafeBrowsingBlockingPageBrowserTest,
705                         testing::Values(2, 3));
706 
707 // TODO(linux_aura) http://crbug.com/163931
708 // TODO(win_aura) http://crbug.com/154081
709 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
710 #define MAYBE_MalwareRedirectInIFrameCanceled DISABLED_MalwareRedirectInIFrameCanceled
711 #else
712 #define MAYBE_MalwareRedirectInIFrameCanceled MalwareRedirectInIFrameCanceled
713 #endif
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MAYBE_MalwareRedirectInIFrameCanceled)714 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
715                        MAYBE_MalwareRedirectInIFrameCanceled) {
716   // 1. Test the case that redirect is a subresource.
717   MalwareRedirectCancelAndProceed("openWinIFrame");
718   // If the redirect was from subresource but canceled, "proceed" will continue
719   // with the rest of resources.
720   AssertNoInterstitial(true);
721 }
722 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareRedirectCanceled)723 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
724                        MalwareRedirectCanceled) {
725   // 2. Test the case that redirect is the only resource.
726   MalwareRedirectCancelAndProceed("openWin");
727   // Clicking proceed won't do anything if the main request is cancelled
728   // already.  See crbug.com/76460.
729   EXPECT_TRUE(YesInterstitial());
730 }
731 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareDontProceed)732 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
733                        MalwareDontProceed) {
734 #if defined(OS_WIN) && defined(USE_ASH)
735   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
736   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
737     return;
738 #endif
739 
740   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
741 
742   if (GetParam() == 2) {
743     EXPECT_EQ(VISIBLE, GetVisibility("malware-icon"));
744     EXPECT_EQ(HIDDEN, GetVisibility("subresource-icon"));
745     EXPECT_EQ(HIDDEN, GetVisibility("phishing-icon"));
746     EXPECT_EQ(VISIBLE, GetVisibility("check-report"));
747     EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
748     EXPECT_EQ(HIDDEN, GetVisibility("report-error-link"));
749     EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
750     EXPECT_TRUE(Click("see-more-link"));
751     EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link"));
752     EXPECT_EQ(HIDDEN, GetVisibility("report-error-link"));
753     EXPECT_EQ(VISIBLE, GetVisibility("proceed"));
754     EXPECT_TRUE(ClickAndWaitForDetach("back"));
755   } else {
756     EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
757     EXPECT_EQ(HIDDEN, GetVisibility("details"));
758     EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
759     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
760     EXPECT_TRUE(Click("details-button"));
761     EXPECT_EQ(VISIBLE, GetVisibility("details"));
762     EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
763     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
764     EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
765   }
766 
767   AssertNoInterstitial(false);   // Assert the interstitial is gone
768   EXPECT_EQ(GURL(url::kAboutBlankURL),  // Back to "about:blank"
769             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
770 }
771 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareProceed)772 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, MalwareProceed) {
773   GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
774 
775   if (GetParam() == 2)
776     EXPECT_TRUE(ClickAndWaitForDetach("proceed"));
777   else
778     EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
779   AssertNoInterstitial(true);  // Assert the interstitial is gone.
780   EXPECT_EQ(url,
781             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
782 }
783 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareLearnMoreV2)784 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
785                        MalwareLearnMoreV2) {
786   if (GetParam() == 3) return;  // Don't have this link in V3.
787   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
788 
789   EXPECT_TRUE(ClickAndWaitForDetach("learn-more-link"));
790   AssertNoInterstitial(false);  // Assert the interstitial is gone
791 
792   // We are in the help page.
793   EXPECT_EQ(
794       "/transparencyreport/safebrowsing/",
795        browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());
796 }
797 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareIframeDontProceed)798 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
799                        MalwareIframeDontProceed) {
800 #if defined(OS_WIN) && defined(USE_ASH)
801   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
802   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
803     return;
804 #endif
805 
806   SetupMalwareIframeWarningAndNavigate();
807 
808   if (GetParam() == 2) {
809     EXPECT_EQ(HIDDEN, GetVisibility("malware-icon"));
810     EXPECT_EQ(VISIBLE, GetVisibility("subresource-icon"));
811     EXPECT_EQ(HIDDEN, GetVisibility("phishing-icon"));
812     EXPECT_EQ(VISIBLE, GetVisibility("check-report"));
813     EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
814     EXPECT_EQ(HIDDEN, GetVisibility("report-error-link"));
815     EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
816     EXPECT_TRUE(Click("see-more-link"));
817     EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link"));
818     EXPECT_EQ(HIDDEN, GetVisibility("report-error-link"));
819     EXPECT_EQ(VISIBLE, GetVisibility("proceed"));
820     EXPECT_TRUE(ClickAndWaitForDetach("back"));
821   } else {
822     EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
823     EXPECT_EQ(HIDDEN, GetVisibility("details"));
824     EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
825     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
826     EXPECT_TRUE(Click("details-button"));
827     EXPECT_EQ(VISIBLE, GetVisibility("details"));
828     EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
829     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
830     EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
831   }
832 
833   AssertNoInterstitial(false);  // Assert the interstitial is gone
834 
835   EXPECT_EQ(GURL(url::kAboutBlankURL),  // Back to "about:blank"
836             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
837 }
838 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MalwareIframeProceed)839 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
840     MalwareIframeProceed) {
841   GURL url = SetupMalwareIframeWarningAndNavigate();
842 
843   if (GetParam() == 2)
844     EXPECT_TRUE(ClickAndWaitForDetach("proceed"));
845   else
846     EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
847   AssertNoInterstitial(true);  // Assert the interstitial is gone
848 
849   EXPECT_EQ(url,
850             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
851 }
852 
853 // http://crbug.com/273302
854 #if defined(OS_WIN)
855 // Temporarily re-enabled to get some logs.
856 #define MAYBE_MalwareIframeReportDetails MalwareIframeReportDetails
857 #else
858 #define MAYBE_MalwareIframeReportDetails MalwareIframeReportDetails
859 #endif
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MAYBE_MalwareIframeReportDetails)860 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
861                        MAYBE_MalwareIframeReportDetails) {
862   // TODO(felt): Enable for V3 when the checkbox is added.
863   if (GetParam() == 3) return;
864 
865   scoped_refptr<content::MessageLoopRunner> malware_report_sent_runner(
866       new content::MessageLoopRunner);
867   SetReportSentCallback(malware_report_sent_runner->QuitClosure());
868 
869   GURL url = SetupMalwareIframeWarningAndNavigate();
870 
871   LOG(INFO) << "1";
872 
873   // If the DOM details from renderer did not already return, wait for them.
874   details_factory_.get_details()->WaitForDOM();
875   LOG(INFO) << "2";
876 
877   EXPECT_TRUE(Click("check-report"));
878   LOG(INFO) << "3";
879 
880   EXPECT_TRUE(ClickAndWaitForDetach("proceed"));
881   LOG(INFO) << "4";
882   AssertNoInterstitial(true);  // Assert the interstitial is gone
883   LOG(INFO) << "5";
884 
885   ASSERT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
886       prefs::kSafeBrowsingExtendedReportingEnabled));
887   LOG(INFO) << "6";
888 
889   EXPECT_EQ(url,
890             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
891   LOG(INFO) << "7";
892 
893   malware_report_sent_runner->Run();
894   std::string serialized = GetReportSent();
895   safe_browsing::ClientMalwareReportRequest report;
896   ASSERT_TRUE(report.ParseFromString(serialized));
897   // Verify the report is complete.
898   EXPECT_TRUE(report.complete());
899   LOG(INFO) << "8";
900 }
901 
902 // Verifies that the "proceed anyway" link isn't available when it is disabled
903 // by the corresponding policy. Also verifies that sending the "proceed"
904 // command anyway doesn't advance to the malware site.
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,ProceedDisabled)905 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) {
906 #if defined(OS_WIN) && defined(USE_ASH)
907   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
908   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
909     return;
910 #endif
911   if (GetParam() == 3) return;
912 
913   // Simulate a policy disabling the "proceed anyway" link.
914   browser()->profile()->GetPrefs()->SetBoolean(
915       prefs::kSafeBrowsingProceedAnywayDisabled, true);
916 
917   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_MALWARE);
918 
919   if (GetParam() == 2) {
920     EXPECT_EQ(VISIBLE, GetVisibility("check-report"));
921     EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
922     EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
923     EXPECT_EQ(HIDDEN, GetVisibility("proceed-span"));
924     EXPECT_TRUE(Click("see-more-link"));
925     EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link"));
926     EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
927     EXPECT_EQ(HIDDEN, GetVisibility("proceed-span"));
928     EXPECT_TRUE(ClickAndWaitForDetach("proceed"));
929   } else {
930     EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
931     EXPECT_EQ(HIDDEN, GetVisibility("details"));
932     EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
933     EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
934     EXPECT_TRUE(Click("details-button"));
935     EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
936     EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
937     SendCommand("proceed");
938   }
939 
940   // The "proceed" command should go back instead, if proceeding is disabled.
941   AssertNoInterstitial(true);
942   EXPECT_EQ(GURL(url::kAboutBlankURL),  // Back to "about:blank"
943             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
944 }
945 
946 // Verifies that the reporting checkbox is hidden on non-HTTP pages.
947 // TODO(mattm): Should also verify that no report is sent, but there isn't a
948 // good way to do that in the current design.
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,ReportingDisabled)949 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ReportingDisabled) {
950 #if defined(OS_WIN) && defined(USE_ASH)
951   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
952   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
953     return;
954 #endif
955   // TODO(felt): Enable for V3 when the checkbox is added.
956   if (GetParam() == 3) return;
957 
958   browser()->profile()->GetPrefs()->SetBoolean(
959       prefs::kSafeBrowsingExtendedReportingEnabled, true);
960 
961   net::SpawnedTestServer https_server(
962       net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
963       base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
964   ASSERT_TRUE(https_server.Start());
965   GURL url = https_server.GetURL(kEmptyPage);
966   SetURLThreatType(url, SB_THREAT_TYPE_URL_MALWARE);
967   ui_test_utils::NavigateToURL(browser(), url);
968   ASSERT_TRUE(WaitForReady());
969 
970   EXPECT_EQ(HIDDEN, GetVisibility("check-report"));
971   EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
972   EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
973   EXPECT_TRUE(Click("see-more-link"));
974   EXPECT_EQ(VISIBLE, GetVisibility("show-diagnostic-link"));
975   EXPECT_EQ(VISIBLE, GetVisibility("proceed"));
976 
977   EXPECT_TRUE(ClickAndWaitForDetach("back"));
978   AssertNoInterstitial(false);   // Assert the interstitial is gone
979   EXPECT_EQ(GURL(url::kAboutBlankURL),  // Back to "about:blank"
980             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
981 }
982 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,PhishingDontProceed)983 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
984     PhishingDontProceed) {
985 #if defined(OS_WIN) && defined(USE_ASH)
986   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
987   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
988     return;
989 #endif
990 
991   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
992 
993   if (GetParam() == 2) {
994     EXPECT_EQ(HIDDEN, GetVisibility("malware-icon"));
995     EXPECT_EQ(HIDDEN, GetVisibility("subresource-icon"));
996     EXPECT_EQ(VISIBLE, GetVisibility("phishing-icon"));
997     EXPECT_EQ(HIDDEN, GetVisibility("check-report"));
998     EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
999     EXPECT_EQ(HIDDEN, GetVisibility("report-error-link"));
1000     EXPECT_EQ(HIDDEN, GetVisibility("proceed"));
1001     EXPECT_TRUE(Click("see-more-link"));
1002     EXPECT_EQ(HIDDEN, GetVisibility("show-diagnostic-link"));
1003     EXPECT_EQ(VISIBLE, GetVisibility("report-error-link"));
1004     EXPECT_EQ(VISIBLE, GetVisibility("proceed"));
1005     EXPECT_TRUE(ClickAndWaitForDetach("back"));
1006   } else {
1007     EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
1008     EXPECT_EQ(HIDDEN, GetVisibility("details"));
1009     EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
1010     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
1011     EXPECT_TRUE(Click("details-button"));
1012     EXPECT_EQ(VISIBLE, GetVisibility("details"));
1013     EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
1014     EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
1015     EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
1016   }
1017 
1018   AssertNoInterstitial(false);  // Assert the interstitial is gone
1019   EXPECT_EQ(GURL(url::kAboutBlankURL),  // We are back to "about:blank".
1020             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1021 }
1022 
1023 // http://crbug.com/247763
1024 #if defined(OS_WIN)
1025 // Temporarily re-enabled to get some logs.
1026 #define MAYBE_PhishingProceed PhishingProceed
1027 #else
1028 #define MAYBE_PhishingProceed PhishingProceed
1029 #endif
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MAYBE_PhishingProceed)1030 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
1031     MAYBE_PhishingProceed) {
1032   GURL url = SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
1033   LOG(INFO) << "1";
1034 
1035   if (GetParam() == 2)
1036     EXPECT_TRUE(ClickAndWaitForDetach("proceed"));
1037   else
1038     EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
1039   LOG(INFO) << "2";
1040   AssertNoInterstitial(true);  // Assert the interstitial is gone
1041   LOG(INFO) << "3";
1042   EXPECT_EQ(url,
1043             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
1044   LOG(INFO) << "4";
1045 }
1046 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,PhishingReportErrorV2)1047 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
1048     PhishingReportErrorV2) {
1049   if (GetParam() == 3) return;  // Not supported in V3.
1050   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
1051 
1052   EXPECT_TRUE(ClickAndWaitForDetach("report-error-link"));
1053   AssertNoInterstitial(false);  // Assert the interstitial is gone
1054 
1055   // We are in the error reporting page.
1056   EXPECT_EQ(
1057       "/safebrowsing/report_error/",
1058       browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());
1059 }
1060 
1061 // See crbug.com/248447
1062 #if defined(OS_WIN)
1063 // Temporarily re-enabled to get some logs.
1064 #define MAYBE_PhishingLearnMore PhishingLearnMore
1065 #else
1066 #define MAYBE_PhishingLearnMore PhishingLearnMore
1067 #endif
1068 
IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,MAYBE_PhishingLearnMore)1069 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
1070     MAYBE_PhishingLearnMore) {
1071   SetupWarningAndNavigate(SB_THREAT_TYPE_URL_PHISHING);
1072   LOG(INFO) << "1";
1073 
1074   if (GetParam() == 2)
1075     EXPECT_TRUE(ClickAndWaitForDetach("learn-more-link"));
1076   else
1077     EXPECT_TRUE(ClickAndWaitForDetach("help-link"));
1078   LOG(INFO) << "2";
1079   AssertNoInterstitial(false);  // Assert the interstitial is gone
1080 
1081   LOG(INFO) << "3";
1082   // We are in the help page.
1083   EXPECT_EQ(
1084       "/transparencyreport/safebrowsing/",
1085        browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());
1086   LOG(INFO) << "4";
1087 }
1088