Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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 "base/memory/ref_counted.h"
      6 #include "base/stringprintf.h"
      7 #include "chrome/browser/debugger/devtools_client_host.h"
      8 #include "chrome/browser/debugger/devtools_manager.h"
      9 #include "chrome/browser/extensions/extension_devtools_browsertest.h"
     10 #include "chrome/browser/extensions/extension_error_reporter.h"
     11 #include "chrome/browser/extensions/extension_host.h"
     12 #include "chrome/browser/extensions/extension_process_manager.h"
     13 #include "chrome/browser/extensions/extension_service.h"
     14 #include "chrome/browser/extensions/extension_tabs_module.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/browser/tabs/tab_strip_model.h"
     17 #include "chrome/browser/ui/browser_list.h"
     18 #include "chrome/common/chrome_paths.h"
     19 #include "chrome/common/devtools_messages.h"
     20 #include "chrome/common/url_constants.h"
     21 #include "chrome/test/ui_test_utils.h"
     22 #include "content/browser/renderer_host/render_view_host.h"
     23 #include "content/browser/site_instance.h"
     24 #include "content/browser/tab_contents/tab_contents.h"
     25 #include "net/base/net_util.h"
     26 
     27 // Looks for an ExtensionHost whose URL has the given path component (including
     28 // leading slash).  Also verifies that the expected number of hosts are loaded.
     29 static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
     30                                        const std::string& path,
     31                                        int expected_hosts) {
     32   ExtensionHost* host = NULL;
     33   int num_hosts = 0;
     34   for (ExtensionProcessManager::const_iterator iter = manager->begin();
     35        iter != manager->end(); ++iter) {
     36     if ((*iter)->GetURL().path() == path) {
     37       EXPECT_FALSE(host);
     38       host = *iter;
     39     }
     40     num_hosts++;
     41   }
     42   EXPECT_EQ(expected_hosts, num_hosts);
     43   EXPECT_TRUE(host);
     44   return host;
     45 }
     46 
     47 // Tests for the experimental timeline extensions API.
     48 // TODO(johnnyg): crbug.com/52544 Test was broken by webkit r65510.
     49 IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, FLAKY_TimelineApi) {
     50   ASSERT_TRUE(LoadExtension(
     51       test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));
     52 
     53   // Get the ExtensionHost that is hosting our background page.
     54   ExtensionProcessManager* manager =
     55       browser()->profile()->GetExtensionProcessManager();
     56   ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
     57 
     58   // Grab a handle to the DevToolsManager so we can forward messages to it.
     59   DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
     60 
     61   // Grab the tab_id of whatever tab happens to be first.
     62   TabContents* tab_contents = browser()->GetTabContentsAt(0);
     63   ASSERT_TRUE(tab_contents);
     64   int tab_id = ExtensionTabUtil::GetTabId(tab_contents);
     65 
     66   // Test setup.
     67   bool result = false;
     68   std::wstring register_listeners_js = base::StringPrintf(
     69       L"setListenersOnTab(%d)", tab_id);
     70   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
     71       host->render_view_host(), L"", register_listeners_js, &result));
     72   EXPECT_TRUE(result);
     73 
     74   // Setting the events should have caused an ExtensionDevToolsBridge to be
     75   // registered for the tab's RenderViewHost.
     76   DevToolsClientHost* devtools_client_host =
     77       devtools_manager->GetDevToolsClientHostFor(
     78           tab_contents->render_view_host());
     79   ASSERT_TRUE(devtools_client_host);
     80 
     81   // Test onPageEvent event.
     82   result = false;
     83 
     84   DevToolsClientMsg_DispatchOnInspectorFrontend pageEventMessage("");
     85   devtools_client_host->SendMessageToClient(pageEventMessage);
     86   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
     87       host->render_view_host(), L"", L"testReceivePageEvent()", &result));
     88   EXPECT_TRUE(result);
     89 
     90   // Test onTabClose event.
     91   result = false;
     92   devtools_manager->UnregisterDevToolsClientHostFor(
     93       tab_contents->render_view_host());
     94   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
     95       host->render_view_host(), L"", L"testReceiveTabCloseEvent()", &result));
     96   EXPECT_TRUE(result);
     97 }
     98 
     99 
    100 // Tests that ref counting of listeners from multiple processes works.
    101 IN_PROC_BROWSER_TEST_F(ExtensionDevToolsBrowserTest, ProcessRefCounting) {
    102   ASSERT_TRUE(LoadExtension(
    103       test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api")));
    104 
    105   // Get the ExtensionHost that is hosting our background page.
    106   ExtensionProcessManager* manager =
    107       browser()->profile()->GetExtensionProcessManager();
    108   ExtensionHost* host_one = FindHostWithPath(manager, "/background.html", 1);
    109 
    110   ASSERT_TRUE(LoadExtension(
    111       test_data_dir_.AppendASCII("devtools").AppendASCII("timeline_api_two")));
    112   ExtensionHost* host_two = FindHostWithPath(manager,
    113                                              "/background_two.html", 2);
    114 
    115   DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
    116 
    117   // Grab the tab_id of whatever tab happens to be first.
    118   TabContents* tab_contents = browser()->GetTabContentsAt(0);
    119   ASSERT_TRUE(tab_contents);
    120   int tab_id = ExtensionTabUtil::GetTabId(tab_contents);
    121 
    122   // Test setup.
    123   bool result = false;
    124   std::wstring register_listeners_js = base::StringPrintf(
    125       L"setListenersOnTab(%d)", tab_id);
    126   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    127       host_one->render_view_host(), L"", register_listeners_js, &result));
    128   EXPECT_TRUE(result);
    129 
    130   // Setting the event listeners should have caused an ExtensionDevToolsBridge
    131   // to be registered for the tab's RenderViewHost.
    132   ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
    133       tab_contents->render_view_host()));
    134 
    135   // Register listeners from the second extension as well.
    136   std::wstring script = base::StringPrintf(L"registerListenersForTab(%d)",
    137                                            tab_id);
    138   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    139       host_two->render_view_host(), L"", script, &result));
    140   EXPECT_TRUE(result);
    141 
    142   // Removing the listeners from the first extension should leave the bridge
    143   // alive.
    144   result = false;
    145   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    146       host_one->render_view_host(), L"", L"unregisterListeners()", &result));
    147   EXPECT_TRUE(result);
    148   ASSERT_TRUE(devtools_manager->GetDevToolsClientHostFor(
    149       tab_contents->render_view_host()));
    150 
    151   // Removing the listeners from the second extension should tear the bridge
    152   // down.
    153   result = false;
    154   ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    155       host_two->render_view_host(), L"", L"unregisterListeners()", &result));
    156   EXPECT_TRUE(result);
    157   ASSERT_FALSE(devtools_manager->GetDevToolsClientHostFor(
    158       tab_contents->render_view_host()));
    159 }
    160