Home | History | Annotate | Download | only in web_navigation
      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 <list>
      6 #include <set>
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "chrome/app/chrome_command_ids.h"
     13 #include "chrome/browser/browser_process.h"
     14 #include "chrome/browser/chrome_browser_main.h"
     15 #include "chrome/browser/chrome_browser_main_extra_parts.h"
     16 #include "chrome/browser/chrome_content_browser_client.h"
     17 #include "chrome/browser/chrome_notification_types.h"
     18 #include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
     19 #include "chrome/browser/extensions/extension_apitest.h"
     20 #include "chrome/browser/extensions/extension_service.h"
     21 #include "chrome/browser/extensions/extension_system.h"
     22 #include "chrome/browser/profiles/profile.h"
     23 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h"
     24 #include "chrome/browser/tab_contents/render_view_context_menu.h"
     25 #include "chrome/browser/ui/browser.h"
     26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     27 #include "chrome/test/base/ui_test_utils.h"
     28 #include "content/public/browser/browser_thread.h"
     29 #include "content/public/browser/render_process_host.h"
     30 #include "content/public/browser/render_view_host.h"
     31 #include "content/public/browser/resource_controller.h"
     32 #include "content/public/browser/resource_dispatcher_host.h"
     33 #include "content/public/browser/resource_throttle.h"
     34 #include "content/public/browser/web_contents.h"
     35 #include "content/public/common/context_menu_params.h"
     36 #include "content/public/common/url_constants.h"
     37 #include "content/public/test/browser_test_utils.h"
     38 #include "extensions/common/switches.h"
     39 #include "net/dns/mock_host_resolver.h"
     40 #include "net/test/embedded_test_server/embedded_test_server.h"
     41 #include "third_party/WebKit/public/web/WebContextMenuData.h"
     42 #include "third_party/WebKit/public/web/WebInputEvent.h"
     43 #include "webkit/common/resource_type.h"
     44 
     45 using content::WebContents;
     46 
     47 namespace extensions {
     48 
     49 namespace {
     50 
     51 // An UI-less RenderViewContextMenu.
     52 class TestRenderViewContextMenu : public RenderViewContextMenu {
     53  public:
     54   TestRenderViewContextMenu(WebContents* web_contents,
     55                             const content::ContextMenuParams& params)
     56       : RenderViewContextMenu(web_contents, params) {
     57   }
     58   virtual ~TestRenderViewContextMenu() {}
     59 
     60  private:
     61   virtual void PlatformInit() OVERRIDE {}
     62   virtual void PlatformCancel() OVERRIDE {}
     63   virtual bool GetAcceleratorForCommandId(int, ui::Accelerator*) OVERRIDE {
     64     return false;
     65   }
     66 
     67   DISALLOW_COPY_AND_ASSIGN(TestRenderViewContextMenu);
     68 };
     69 
     70 
     71 // This class can defer requests for arbitrary URLs.
     72 class TestNavigationListener
     73     : public base::RefCountedThreadSafe<TestNavigationListener> {
     74  public:
     75   TestNavigationListener() {}
     76 
     77   // Add |url| to the set of URLs we should delay.
     78   void DelayRequestsForURL(const GURL& url) {
     79     if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
     80       content::BrowserThread::PostTask(
     81           content::BrowserThread::IO,
     82           FROM_HERE,
     83           base::Bind(&TestNavigationListener::DelayRequestsForURL, this, url));
     84       return;
     85     }
     86     urls_to_delay_.insert(url);
     87   }
     88 
     89   // Resume all deferred requests.
     90   void ResumeAll() {
     91     if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
     92       content::BrowserThread::PostTask(
     93           content::BrowserThread::IO,
     94           FROM_HERE,
     95           base::Bind(&TestNavigationListener::ResumeAll, this));
     96       return;
     97     }
     98     WeakThrottleList::const_iterator it;
     99     for (it = throttles_.begin(); it != throttles_.end(); ++it) {
    100       if (it->get())
    101         (*it)->Resume();
    102     }
    103     throttles_.clear();
    104   }
    105 
    106   // Constructs a ResourceThrottle if the request for |url| should be held.
    107   //
    108   // Needs to be invoked on the IO thread.
    109   content::ResourceThrottle* CreateResourceThrottle(
    110       const GURL& url,
    111       ResourceType::Type resource_type) {
    112     DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
    113     if (urls_to_delay_.find(url) == urls_to_delay_.end())
    114       return NULL;
    115 
    116     Throttle* throttle = new Throttle();
    117     throttles_.push_back(throttle->AsWeakPtr());
    118     return throttle;
    119   }
    120 
    121  private:
    122   friend class base::RefCountedThreadSafe<TestNavigationListener>;
    123 
    124   virtual ~TestNavigationListener() {}
    125 
    126   // Stores a throttle per URL request that we have delayed.
    127   class Throttle : public content::ResourceThrottle,
    128                    public base::SupportsWeakPtr<Throttle> {
    129    public:
    130     void Resume() {
    131       controller()->Resume();
    132     }
    133 
    134     // content::ResourceThrottle implementation.
    135     virtual void WillStartRequest(bool* defer) OVERRIDE {
    136       *defer = true;
    137     }
    138   };
    139   typedef base::WeakPtr<Throttle> WeakThrottle;
    140   typedef std::list<WeakThrottle> WeakThrottleList;
    141   WeakThrottleList throttles_;
    142 
    143   // The set of URLs to be delayed.
    144   std::set<GURL> urls_to_delay_;
    145 
    146   DISALLOW_COPY_AND_ASSIGN(TestNavigationListener);
    147 };
    148 
    149 // Waits for a WC to be created. Once it starts loading |delay_url| (after at
    150 // least the first navigation has committed), it delays the load, executes
    151 // |script| in the last committed RVH and resumes the load when |until_url|
    152 // commits. This class expects |script| to trigger the load of |until_url|.
    153 class DelayLoadStartAndExecuteJavascript
    154     : public content::NotificationObserver,
    155       public content::WebContentsObserver {
    156  public:
    157   DelayLoadStartAndExecuteJavascript(
    158       TestNavigationListener* test_navigation_listener,
    159       const GURL& delay_url,
    160       const std::string& script,
    161       const GURL& until_url)
    162       : content::WebContentsObserver(),
    163         test_navigation_listener_(test_navigation_listener),
    164         delay_url_(delay_url),
    165         until_url_(until_url),
    166         script_(script),
    167         script_was_executed_(false),
    168         rvh_(NULL) {
    169     registrar_.Add(this,
    170                    chrome::NOTIFICATION_TAB_ADDED,
    171                    content::NotificationService::AllSources());
    172     test_navigation_listener_->DelayRequestsForURL(delay_url_);
    173   }
    174   virtual ~DelayLoadStartAndExecuteJavascript() {}
    175 
    176   virtual void Observe(int type,
    177                        const content::NotificationSource& source,
    178                        const content::NotificationDetails& details) OVERRIDE {
    179     if (type != chrome::NOTIFICATION_TAB_ADDED) {
    180       NOTREACHED();
    181       return;
    182     }
    183     content::WebContentsObserver::Observe(
    184         content::Details<content::WebContents>(details).ptr());
    185     registrar_.RemoveAll();
    186   }
    187 
    188   virtual void DidStartProvisionalLoadForFrame(
    189       int64 frame_id,
    190       int64 parent_frame_id,
    191       bool is_main_frame,
    192       const GURL& validated_url,
    193       bool is_error_page,
    194       bool is_iframe_srcdoc,
    195       content::RenderViewHost* render_view_host) OVERRIDE {
    196     if (validated_url != delay_url_ || !rvh_)
    197       return;
    198 
    199     rvh_->ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(script_));
    200     script_was_executed_ = true;
    201   }
    202 
    203   virtual void DidCommitProvisionalLoadForFrame(
    204       int64 frame_id,
    205       bool is_main_frame,
    206       const GURL& url,
    207       content::PageTransition transition_type,
    208       content::RenderViewHost* render_view_host) OVERRIDE {
    209     if (script_was_executed_ && url == until_url_) {
    210       content::WebContentsObserver::Observe(NULL);
    211       test_navigation_listener_->ResumeAll();
    212     }
    213     rvh_ = render_view_host;
    214   }
    215 
    216  private:
    217   content::NotificationRegistrar registrar_;
    218 
    219   scoped_refptr<TestNavigationListener> test_navigation_listener_;
    220 
    221   GURL delay_url_;
    222   GURL until_url_;
    223   std::string script_;
    224   bool script_was_executed_;
    225   content::RenderViewHost* rvh_;
    226 
    227   DISALLOW_COPY_AND_ASSIGN(DelayLoadStartAndExecuteJavascript);
    228 };
    229 
    230 // A ResourceDispatcherHostDelegate that adds a TestNavigationObserver.
    231 class TestResourceDispatcherHostDelegate
    232     : public ChromeResourceDispatcherHostDelegate {
    233  public:
    234   TestResourceDispatcherHostDelegate(
    235       prerender::PrerenderTracker* prerender_tracker,
    236       TestNavigationListener* test_navigation_listener)
    237       : ChromeResourceDispatcherHostDelegate(prerender_tracker),
    238         test_navigation_listener_(test_navigation_listener) {
    239   }
    240   virtual ~TestResourceDispatcherHostDelegate() {}
    241 
    242   virtual void RequestBeginning(
    243       net::URLRequest* request,
    244       content::ResourceContext* resource_context,
    245       appcache::AppCacheService* appcache_service,
    246       ResourceType::Type resource_type,
    247       int child_id,
    248       int route_id,
    249       bool is_continuation_of_transferred_request,
    250       ScopedVector<content::ResourceThrottle>* throttles) OVERRIDE {
    251     ChromeResourceDispatcherHostDelegate::RequestBeginning(
    252         request,
    253         resource_context,
    254         appcache_service,
    255         resource_type,
    256         child_id,
    257         route_id,
    258         is_continuation_of_transferred_request,
    259         throttles);
    260     content::ResourceThrottle* throttle =
    261         test_navigation_listener_->CreateResourceThrottle(request->url(),
    262                                                           resource_type);
    263     if (throttle)
    264       throttles->push_back(throttle);
    265   }
    266 
    267  private:
    268   scoped_refptr<TestNavigationListener> test_navigation_listener_;
    269 
    270   DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
    271 };
    272 
    273 // Used to manage the lifetime of the TestResourceDispatcherHostDelegate which
    274 // needs to be deleted before the threads are stopped.
    275 class TestBrowserMainExtraParts : public ChromeBrowserMainExtraParts {
    276  public:
    277   explicit TestBrowserMainExtraParts(
    278       TestNavigationListener* test_navigation_listener)
    279       : test_navigation_listener_(test_navigation_listener) {
    280   }
    281   virtual ~TestBrowserMainExtraParts() {}
    282 
    283   TestResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() {
    284     if (!resource_dispatcher_host_delegate_.get()) {
    285       resource_dispatcher_host_delegate_.reset(
    286           new TestResourceDispatcherHostDelegate(
    287               g_browser_process->prerender_tracker(),
    288               test_navigation_listener_.get()));
    289     }
    290     return resource_dispatcher_host_delegate_.get();
    291   }
    292 
    293   // ChromeBrowserMainExtraParts implementation.
    294   virtual void PostMainMessageLoopRun() OVERRIDE {
    295     resource_dispatcher_host_delegate_.reset();
    296   }
    297 
    298  private:
    299   scoped_refptr<TestNavigationListener> test_navigation_listener_;
    300   scoped_ptr<TestResourceDispatcherHostDelegate>
    301       resource_dispatcher_host_delegate_;
    302 
    303   DISALLOW_COPY_AND_ASSIGN(TestBrowserMainExtraParts);
    304 };
    305 
    306 // A ContentBrowserClient that doesn't forward the RDH created signal.
    307 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient {
    308  public:
    309   explicit TestContentBrowserClient(
    310       TestNavigationListener* test_navigation_listener)
    311       : test_navigation_listener_(test_navigation_listener) {
    312   }
    313   virtual ~TestContentBrowserClient() {}
    314 
    315   virtual void ResourceDispatcherHostCreated() OVERRIDE {
    316     // Don't invoke ChromeContentBrowserClient::ResourceDispatcherHostCreated.
    317     // It would notify BrowserProcessImpl which would create a
    318     // ChromeResourceDispatcherHostDelegate and other objects. Not creating
    319     // other objects might turn out to be a problem in the future.
    320     content::ResourceDispatcherHost::Get()->SetDelegate(
    321         browser_main_extra_parts_->resource_dispatcher_host_delegate());
    322   }
    323 
    324   virtual content::BrowserMainParts* CreateBrowserMainParts(
    325       const content::MainFunctionParams& parameters) OVERRIDE {
    326     ChromeBrowserMainParts* main_parts = static_cast<ChromeBrowserMainParts*>(
    327         ChromeContentBrowserClient::CreateBrowserMainParts(parameters));
    328 
    329     browser_main_extra_parts_ =
    330         new TestBrowserMainExtraParts(test_navigation_listener_.get());
    331     main_parts->AddParts(browser_main_extra_parts_);
    332     return main_parts;
    333   }
    334 
    335  private:
    336   scoped_refptr<TestNavigationListener> test_navigation_listener_;
    337   TestBrowserMainExtraParts* browser_main_extra_parts_;
    338 
    339   DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient);
    340 };
    341 
    342 }  // namespace
    343 
    344 class WebNavigationApiTest : public ExtensionApiTest {
    345  public:
    346   WebNavigationApiTest() {}
    347   virtual ~WebNavigationApiTest() {}
    348 
    349   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    350     ExtensionApiTest::SetUpInProcessBrowserTestFixture();
    351 
    352     test_navigation_listener_ = new TestNavigationListener();
    353     content_browser_client_.reset(
    354         new TestContentBrowserClient(test_navigation_listener_.get()));
    355     original_content_browser_client_ = content::SetBrowserClientForTesting(
    356         content_browser_client_.get());
    357 
    358     FrameNavigationState::set_allow_extension_scheme(true);
    359 
    360     CommandLine::ForCurrentProcess()->AppendSwitch(
    361         switches::kAllowLegacyExtensionManifests);
    362 
    363     host_resolver()->AddRule("*", "127.0.0.1");
    364   }
    365 
    366   virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    367     ExtensionApiTest::TearDownInProcessBrowserTestFixture();
    368     content::SetBrowserClientForTesting(original_content_browser_client_);
    369   }
    370 
    371   TestNavigationListener* test_navigation_listener() {
    372     return test_navigation_listener_.get();
    373   }
    374 
    375  private:
    376   scoped_refptr<TestNavigationListener> test_navigation_listener_;
    377   scoped_ptr<TestContentBrowserClient> content_browser_client_;
    378   content::ContentBrowserClient* original_content_browser_client_;
    379 
    380   DISALLOW_COPY_AND_ASSIGN(WebNavigationApiTest);
    381 };
    382 
    383 // Fails often on Windows dbg bots. http://crbug.com/177163
    384 #if defined(OS_WIN)
    385 #define MAYBE_Api DISABLED_Api
    386 #else
    387 #define MAYBE_Api Api
    388 #endif  // defined(OS_WIN)
    389 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Api) {
    390   ASSERT_TRUE(StartEmbeddedTestServer());
    391   ASSERT_TRUE(
    392       RunExtensionSubtest("webnavigation", "test_api.html")) << message_;
    393 }
    394 
    395 // Fails often on Windows dbg bots. http://crbug.com/177163
    396 #if defined(OS_WIN)
    397 #define MAYBE_GetFrame DISABLED_GetFrame
    398 #else
    399 #define MAYBE_GetFrame GetFrame
    400 #endif  // defined(OS_WIN)
    401 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_GetFrame) {
    402   ASSERT_TRUE(StartEmbeddedTestServer());
    403   ASSERT_TRUE(
    404       RunExtensionSubtest("webnavigation", "test_getFrame.html")) << message_;
    405 }
    406 
    407 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ClientRedirect) {
    408   ASSERT_TRUE(StartEmbeddedTestServer());
    409   ASSERT_TRUE(
    410       RunExtensionSubtest("webnavigation", "test_clientRedirect.html"))
    411           << message_;
    412 }
    413 
    414 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirect) {
    415   ASSERT_TRUE(StartEmbeddedTestServer());
    416   ASSERT_TRUE(
    417       RunExtensionSubtest("webnavigation", "test_serverRedirect.html"))
    418           << message_;
    419 }
    420 
    421 // http://crbug.com/235171 and http://crbug.com/177163
    422 #if (defined(OS_WIN) && !defined(NDEBUG)) || \
    423     (defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(USE_AURA)))
    424 #define MAYBE_ServerRedirectSingleProcess DISABLED_ServerRedirectSingleProcess
    425 #else
    426 #define MAYBE_ServerRedirectSingleProcess ServerRedirectSingleProcess
    427 #endif
    428 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest,
    429                        MAYBE_ServerRedirectSingleProcess) {
    430   ASSERT_TRUE(StartEmbeddedTestServer());
    431 
    432   // Set max renderers to 1 to force running out of processes.
    433   content::RenderProcessHost::SetMaxRendererProcessCount(1);
    434 
    435   // Wait for the extension to set itself up and return control to us.
    436   ASSERT_TRUE(RunExtensionSubtest(
    437       "webnavigation", "test_serverRedirectSingleProcess.html"))
    438           << message_;
    439 
    440   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    441   content::WaitForLoadStop(tab);
    442 
    443   ResultCatcher catcher;
    444   GURL url(base::StringPrintf(
    445       "http://www.a.com:%d/"
    446           "extensions/api_test/webnavigation/serverRedirect/a.html",
    447       embedded_test_server()->port()));
    448 
    449   ui_test_utils::NavigateToURL(browser(), url);
    450 
    451   url = GURL(base::StringPrintf(
    452       "http://www.b.com:%d/server-redirect?http://www.b.com:%d/",
    453       embedded_test_server()->port(),
    454       embedded_test_server()->port()));
    455 
    456   ui_test_utils::NavigateToURL(browser(), url);
    457 
    458   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    459 }
    460 
    461 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ForwardBack) {
    462   ASSERT_TRUE(StartEmbeddedTestServer());
    463   ASSERT_TRUE(
    464       RunExtensionSubtest("webnavigation", "test_forwardBack.html"))
    465           << message_;
    466 }
    467 
    468 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, IFrame) {
    469   ASSERT_TRUE(StartEmbeddedTestServer());
    470   ASSERT_TRUE(
    471       RunExtensionSubtest("webnavigation", "test_iframe.html")) << message_;
    472 }
    473 
    474 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SrcDoc) {
    475   ASSERT_TRUE(StartEmbeddedTestServer());
    476   ASSERT_TRUE(
    477       RunExtensionSubtest("webnavigation", "test_srcdoc.html")) << message_;
    478 }
    479 
    480 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, OpenTab) {
    481   ASSERT_TRUE(StartEmbeddedTestServer());
    482   ASSERT_TRUE(
    483       RunExtensionSubtest("webnavigation", "test_openTab.html")) << message_;
    484 }
    485 
    486 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ReferenceFragment) {
    487   ASSERT_TRUE(StartEmbeddedTestServer());
    488   ASSERT_TRUE(
    489       RunExtensionSubtest("webnavigation", "test_referenceFragment.html"))
    490           << message_;
    491 }
    492 
    493 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, SimpleLoad) {
    494   ASSERT_TRUE(StartEmbeddedTestServer());
    495   ASSERT_TRUE(
    496       RunExtensionSubtest("webnavigation", "test_simpleLoad.html")) << message_;
    497 }
    498 
    499 // Fails often on Windows dbg bots. http://crbug.com/177163
    500 #if defined(OS_WIN)
    501 #define MAYBE_Failures DISABLED_Failures
    502 #else
    503 #define MAYBE_Failures Failures
    504 #endif  // defined(OS_WIN)
    505 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Failures) {
    506   ASSERT_TRUE(StartEmbeddedTestServer());
    507   ASSERT_TRUE(
    508       RunExtensionSubtest("webnavigation", "test_failures.html")) << message_;
    509 }
    510 
    511 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, FilteredTest) {
    512   ASSERT_TRUE(StartEmbeddedTestServer());
    513   ASSERT_TRUE(
    514       RunExtensionSubtest("webnavigation", "test_filtered.html")) << message_;
    515 }
    516 
    517 // Fails often on Windows dbg bots. http://crbug.com/177163
    518 #if defined(OS_WIN)
    519 #define MAYBE_UserAction DISABLED_UserAction
    520 #else
    521 #define MAYBE_UserAction UserAction
    522 #endif  // defined(OS_WIN)
    523 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_UserAction) {
    524   ASSERT_TRUE(StartEmbeddedTestServer());
    525 
    526   // Wait for the extension to set itself up and return control to us.
    527   ASSERT_TRUE(
    528       RunExtensionSubtest("webnavigation", "test_userAction.html")) << message_;
    529 
    530   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    531   content::WaitForLoadStop(tab);
    532 
    533   ResultCatcher catcher;
    534 
    535   ExtensionService* service = extensions::ExtensionSystem::Get(
    536       browser()->profile())->extension_service();
    537   const extensions::Extension* extension =
    538       service->GetExtensionById(last_loaded_extension_id_, false);
    539   GURL url = extension->GetResourceURL("userAction/a.html");
    540 
    541   ui_test_utils::NavigateToURL(browser(), url);
    542 
    543   // This corresponds to "Open link in new tab".
    544   content::ContextMenuParams params;
    545   params.is_editable = false;
    546   params.media_type = WebKit::WebContextMenuData::MediaTypeNone;
    547   params.page_url = url;
    548   params.frame_id = WebNavigationTabObserver::Get(tab)->
    549       frame_navigation_state().GetMainFrameID().frame_num;
    550   params.link_url = extension->GetResourceURL("userAction/b.html");
    551 
    552   TestRenderViewContextMenu menu(tab, params);
    553   menu.Init();
    554   menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0);
    555 
    556   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    557 }
    558 
    559 // http://crbug.com/177163
    560 #if defined(OS_WIN) && !defined(NDEBUG)
    561 #define MAYBE_RequestOpenTab DISABLED_RequestOpenTab
    562 #else
    563 #define MAYBE_RequestOpenTab RequestOpenTab
    564 #endif
    565 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_RequestOpenTab) {
    566   ASSERT_TRUE(StartEmbeddedTestServer());
    567 
    568   // Wait for the extension to set itself up and return control to us.
    569   ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_requestOpenTab.html"))
    570       << message_;
    571 
    572   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    573   content::WaitForLoadStop(tab);
    574 
    575   ResultCatcher catcher;
    576 
    577   ExtensionService* service = extensions::ExtensionSystem::Get(
    578       browser()->profile())->extension_service();
    579   const extensions::Extension* extension =
    580       service->GetExtensionById(last_loaded_extension_id_, false);
    581   GURL url = extension->GetResourceURL("requestOpenTab/a.html");
    582 
    583   ui_test_utils::NavigateToURL(browser(), url);
    584 
    585   // There's a link on a.html. Middle-click on it to open it in a new tab.
    586   WebKit::WebMouseEvent mouse_event;
    587   mouse_event.type = WebKit::WebInputEvent::MouseDown;
    588   mouse_event.button = WebKit::WebMouseEvent::ButtonMiddle;
    589   mouse_event.x = 7;
    590   mouse_event.y = 7;
    591   mouse_event.clickCount = 1;
    592   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    593   mouse_event.type = WebKit::WebInputEvent::MouseUp;
    594   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    595 
    596   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    597 }
    598 
    599 // Fails often on Windows dbg bots. http://crbug.com/177163
    600 #if defined(OS_WIN)
    601 #define MAYBE_TargetBlank DISABLED_TargetBlank
    602 #else
    603 #define MAYBE_TargetBlank TargetBlank
    604 #endif  // defined(OS_WIN)
    605 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_TargetBlank) {
    606   ASSERT_TRUE(StartEmbeddedTestServer());
    607 
    608   // Wait for the extension to set itself up and return control to us.
    609   ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_targetBlank.html"))
    610       << message_;
    611 
    612   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    613   content::WaitForLoadStop(tab);
    614 
    615   ResultCatcher catcher;
    616 
    617   GURL url = embedded_test_server()->GetURL(
    618       "/extensions/api_test/webnavigation/targetBlank/a.html");
    619 
    620   chrome::NavigateParams params(browser(), url, content::PAGE_TRANSITION_LINK);
    621   ui_test_utils::NavigateToURL(&params);
    622 
    623   // There's a link with target=_blank on a.html. Click on it to open it in a
    624   // new tab.
    625   WebKit::WebMouseEvent mouse_event;
    626   mouse_event.type = WebKit::WebInputEvent::MouseDown;
    627   mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
    628   mouse_event.x = 7;
    629   mouse_event.y = 7;
    630   mouse_event.clickCount = 1;
    631   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    632   mouse_event.type = WebKit::WebInputEvent::MouseUp;
    633   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    634 
    635   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    636 }
    637 
    638 // http://crbug.com/177163
    639 #if defined(OS_WIN) && !defined(NDEBUG)
    640 #define MAYBE_TargetBlankIncognito DISABLED_TargetBlankIncognito
    641 #else
    642 #define MAYBE_TargetBlankIncognito TargetBlankIncognito
    643 #endif
    644 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_TargetBlankIncognito) {
    645   ASSERT_TRUE(StartEmbeddedTestServer());
    646 
    647   // Wait for the extension to set itself up and return control to us.
    648   ASSERT_TRUE(RunExtensionSubtest(
    649       "webnavigation", "test_targetBlank.html",
    650       ExtensionApiTest::kFlagEnableIncognito)) << message_;
    651 
    652   ResultCatcher catcher;
    653 
    654   GURL url = embedded_test_server()->GetURL(
    655       "/extensions/api_test/webnavigation/targetBlank/a.html");
    656 
    657   Browser* otr_browser = ui_test_utils::OpenURLOffTheRecord(
    658       browser()->profile(), url);
    659   WebContents* tab = otr_browser->tab_strip_model()->GetActiveWebContents();
    660 
    661   // There's a link with target=_blank on a.html. Click on it to open it in a
    662   // new tab.
    663   WebKit::WebMouseEvent mouse_event;
    664   mouse_event.type = WebKit::WebInputEvent::MouseDown;
    665   mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
    666   mouse_event.x = 7;
    667   mouse_event.y = 7;
    668   mouse_event.clickCount = 1;
    669   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    670   mouse_event.type = WebKit::WebInputEvent::MouseUp;
    671   tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
    672 
    673   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    674 }
    675 
    676 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, History) {
    677   ASSERT_TRUE(StartEmbeddedTestServer());
    678   ASSERT_TRUE(
    679       RunExtensionSubtest("webnavigation", "test_history.html"))
    680           << message_;
    681 }
    682 
    683 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcess) {
    684   ASSERT_TRUE(StartEmbeddedTestServer());
    685 
    686   LoadExtension(test_data_dir_.AppendASCII("webnavigation").AppendASCII("app"));
    687   LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
    688 
    689   ExtensionService* service = extensions::ExtensionSystem::Get(
    690       browser()->profile())->extension_service();
    691   const extensions::Extension* extension =
    692       service->GetExtensionById(last_loaded_extension_id_, false);
    693 
    694   // See crossProcess/d.html.
    695   DelayLoadStartAndExecuteJavascript call_script(
    696       test_navigation_listener(),
    697       embedded_test_server()->GetURL("/test1"),
    698       "navigate2()",
    699       extension->GetResourceURL("crossProcess/empty.html"));
    700 
    701   ASSERT_TRUE(RunPageTest(
    702       extension->GetResourceURL("test_crossProcess.html").spec()))
    703           << message_;
    704 }
    705 
    706 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessFragment) {
    707   ASSERT_TRUE(StartEmbeddedTestServer());
    708 
    709   LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
    710 
    711   ExtensionService* service = extensions::ExtensionSystem::Get(
    712       browser()->profile())->extension_service();
    713   const extensions::Extension* extension =
    714       service->GetExtensionById(last_loaded_extension_id_, false);
    715 
    716   // See crossProcess/f.html.
    717   DelayLoadStartAndExecuteJavascript call_script3(
    718       test_navigation_listener(),
    719       embedded_test_server()->GetURL("/test3"),
    720       "updateFragment()",
    721       extension->GetResourceURL(base::StringPrintf(
    722           "crossProcess/f.html?%d#foo",
    723           embedded_test_server()->port())));
    724 
    725   // See crossProcess/g.html.
    726   DelayLoadStartAndExecuteJavascript call_script4(
    727       test_navigation_listener(),
    728       embedded_test_server()->GetURL("/test4"),
    729       "updateFragment()",
    730       extension->GetResourceURL(base::StringPrintf(
    731           "crossProcess/g.html?%d#foo",
    732           embedded_test_server()->port())));
    733 
    734   ASSERT_TRUE(RunPageTest(
    735       extension->GetResourceURL("test_crossProcessFragment.html").spec()))
    736           << message_;
    737 }
    738 
    739 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, CrossProcessHistory) {
    740   ASSERT_TRUE(StartEmbeddedTestServer());
    741 
    742   LoadExtension(test_data_dir_.AppendASCII("webnavigation"));
    743 
    744   ExtensionService* service = extensions::ExtensionSystem::Get(
    745       browser()->profile())->extension_service();
    746   const extensions::Extension* extension =
    747       service->GetExtensionById(last_loaded_extension_id_, false);
    748 
    749   // See crossProcess/e.html.
    750   DelayLoadStartAndExecuteJavascript call_script2(
    751       test_navigation_listener(),
    752       embedded_test_server()->GetURL("/test2"),
    753       "updateHistory()",
    754       extension->GetResourceURL("crossProcess/empty.html"));
    755 
    756   // See crossProcess/h.html.
    757   DelayLoadStartAndExecuteJavascript call_script5(
    758       test_navigation_listener(),
    759       embedded_test_server()->GetURL("/test5"),
    760       "updateHistory()",
    761       extension->GetResourceURL("crossProcess/empty.html"));
    762 
    763   // See crossProcess/i.html.
    764   DelayLoadStartAndExecuteJavascript call_script6(
    765       test_navigation_listener(),
    766       embedded_test_server()->GetURL("/test6"),
    767       "updateHistory()",
    768       extension->GetResourceURL("crossProcess/empty.html"));
    769 
    770   ASSERT_TRUE(RunPageTest(
    771       extension->GetResourceURL("test_crossProcessHistory.html").spec()))
    772           << message_;
    773 }
    774 
    775 // http://crbug.com/177163
    776 #if defined(OS_WIN) && !defined(NDEBUG)
    777 #define MAYBE_Crash DISABLED_Crash
    778 #else
    779 #define MAYBE_Crash Crash
    780 #endif
    781 IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_Crash) {
    782   ASSERT_TRUE(StartEmbeddedTestServer());
    783 
    784   // Wait for the extension to set itself up and return control to us.
    785   ASSERT_TRUE(RunExtensionSubtest("webnavigation", "test_crash.html"))
    786       << message_;
    787 
    788   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
    789   content::WaitForLoadStop(tab);
    790 
    791   ResultCatcher catcher;
    792 
    793   GURL url(base::StringPrintf(
    794       "http://www.a.com:%d/"
    795           "extensions/api_test/webnavigation/crash/a.html",
    796       embedded_test_server()->port()));
    797   ui_test_utils::NavigateToURL(browser(), url);
    798 
    799   ui_test_utils::NavigateToURL(browser(), GURL(content::kChromeUICrashURL));
    800 
    801   url = GURL(base::StringPrintf(
    802       "http://www.a.com:%d/"
    803           "extensions/api_test/webnavigation/crash/b.html",
    804       embedded_test_server()->port()));
    805   ui_test_utils::NavigateToURL(browser(), url);
    806 
    807   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
    808 }
    809 
    810 }  // namespace extensions
    811