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 <vector>
      6 
      7 #include "base/command_line.h"
      8 #include "base/file_path.h"
      9 #include "base/file_util.h"
     10 #include "base/path_service.h"
     11 #include "chrome/browser/extensions/extension_service.h"
     12 #include "chrome/browser/extensions/user_script_master.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/ui/browser.h"
     15 #include "chrome/common/chrome_paths.h"
     16 #include "chrome/common/chrome_switches.h"
     17 #include "chrome/test/in_process_browser_test.h"
     18 #include "chrome/test/ui_test_utils.h"
     19 #include "content/browser/tab_contents/tab_contents.h"
     20 #include "content/common/notification_details.h"
     21 #include "content/common/notification_type.h"
     22 #include "net/base/net_util.h"
     23 
     24 // This file contains high-level startup tests for the extensions system. We've
     25 // had many silly bugs where command line flags did not get propagated correctly
     26 // into the services, so we didn't start correctly.
     27 
     28 class ExtensionStartupTestBase : public InProcessBrowserTest {
     29  public:
     30   ExtensionStartupTestBase() : enable_extensions_(false) {
     31     num_expected_extensions_ = 3;
     32   }
     33 
     34  protected:
     35   // InProcessBrowserTest
     36   virtual void SetUpCommandLine(CommandLine* command_line) {
     37     EnableDOMAutomation();
     38 
     39     FilePath profile_dir;
     40     PathService::Get(chrome::DIR_USER_DATA, &profile_dir);
     41     profile_dir = profile_dir.AppendASCII("Default");
     42     file_util::CreateDirectory(profile_dir);
     43 
     44     preferences_file_ = profile_dir.AppendASCII("Preferences");
     45     user_scripts_dir_ = profile_dir.AppendASCII("User Scripts");
     46     extensions_dir_ = profile_dir.AppendASCII("Extensions");
     47 
     48     if (enable_extensions_) {
     49       if (load_extension_.empty()) {
     50         FilePath src_dir;
     51         PathService::Get(chrome::DIR_TEST_DATA, &src_dir);
     52         src_dir = src_dir.AppendASCII("extensions").AppendASCII("good");
     53 
     54         file_util::CopyFile(src_dir.AppendASCII("Preferences"),
     55                             preferences_file_);
     56         file_util::CopyDirectory(src_dir.AppendASCII("Extensions"),
     57                                  profile_dir, true);  // recursive
     58       }
     59     } else {
     60       command_line->AppendSwitch(switches::kDisableExtensions);
     61     }
     62 
     63     if (!load_extension_.empty()) {
     64       command_line->AppendSwitchPath(switches::kLoadExtension, load_extension_);
     65       command_line->AppendSwitch(switches::kDisableExtensionsFileAccessCheck);
     66     }
     67   }
     68 
     69   virtual void TearDown() {
     70     EXPECT_TRUE(file_util::Delete(preferences_file_, false));
     71 
     72     // TODO(phajdan.jr): Check return values of the functions below, carefully.
     73     file_util::Delete(user_scripts_dir_, true);
     74     file_util::Delete(extensions_dir_, true);
     75 
     76     InProcessBrowserTest::TearDown();
     77   }
     78 
     79   void WaitForServicesToStart(int num_expected_extensions,
     80                               bool expect_extensions_enabled) {
     81     ExtensionService* service = browser()->profile()->GetExtensionService();
     82 
     83     // Count the number of non-component extensions.
     84     int found_extensions = 0;
     85     for (size_t i = 0; i < service->extensions()->size(); i++)
     86       if (service->extensions()->at(i)->location() != Extension::COMPONENT)
     87         found_extensions++;
     88 
     89     ASSERT_EQ(static_cast<uint32>(num_expected_extensions),
     90               static_cast<uint32>(found_extensions));
     91     ASSERT_EQ(expect_extensions_enabled, service->extensions_enabled());
     92 
     93     UserScriptMaster* master = browser()->profile()->GetUserScriptMaster();
     94     if (!master->ScriptsReady()) {
     95       ui_test_utils::WaitForNotification(
     96           NotificationType::USER_SCRIPTS_UPDATED);
     97     }
     98     ASSERT_TRUE(master->ScriptsReady());
     99   }
    100 
    101   void TestInjection(bool expect_css, bool expect_script) {
    102     // Load a page affected by the content script and test to see the effect.
    103     FilePath test_file;
    104     PathService::Get(chrome::DIR_TEST_DATA, &test_file);
    105     test_file = test_file.AppendASCII("extensions")
    106                          .AppendASCII("test_file.html");
    107 
    108     ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));
    109 
    110     bool result = false;
    111     ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    112         browser()->GetSelectedTabContents()->render_view_host(), L"",
    113         L"window.domAutomationController.send("
    114         L"document.defaultView.getComputedStyle(document.body, null)."
    115         L"getPropertyValue('background-color') == 'rgb(245, 245, 220)')",
    116         &result));
    117     EXPECT_EQ(expect_css, result);
    118 
    119     result = false;
    120     ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
    121         browser()->GetSelectedTabContents()->render_view_host(), L"",
    122         L"window.domAutomationController.send(document.title == 'Modified')",
    123         &result));
    124     EXPECT_EQ(expect_script, result);
    125   }
    126 
    127   FilePath preferences_file_;
    128   FilePath extensions_dir_;
    129   FilePath user_scripts_dir_;
    130   bool enable_extensions_;
    131   FilePath load_extension_;
    132 
    133   int num_expected_extensions_;
    134 };
    135 
    136 
    137 // ExtensionsStartupTest
    138 // Ensures that we can startup the browser with --enable-extensions and some
    139 // extensions installed and see them run and do basic things.
    140 
    141 class ExtensionsStartupTest : public ExtensionStartupTestBase {
    142  public:
    143   ExtensionsStartupTest() {
    144     enable_extensions_ = true;
    145   }
    146 };
    147 
    148 IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, Test) {
    149   WaitForServicesToStart(num_expected_extensions_, true);
    150   TestInjection(true, true);
    151 }
    152 
    153 // Sometimes times out on Mac.  http://crbug.com/48151
    154 #if defined(OS_MACOSX)
    155 #define MAYBE_NoFileAccess DISABLED_NoFileAccess
    156 #else
    157 #define MAYBE_NoFileAccess NoFileAccess
    158 #endif
    159 // Tests that disallowing file access on an extension prevents it from injecting
    160 // script into a page with a file URL.
    161 IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest, MAYBE_NoFileAccess) {
    162   WaitForServicesToStart(num_expected_extensions_, true);
    163 
    164   ExtensionService* service = browser()->profile()->GetExtensionService();
    165   for (size_t i = 0; i < service->extensions()->size(); ++i) {
    166     if (service->extensions()->at(i)->location() == Extension::COMPONENT)
    167       continue;
    168     if (service->AllowFileAccess(service->extensions()->at(i))) {
    169       service->SetAllowFileAccess(service->extensions()->at(i), false);
    170       ui_test_utils::WaitForNotification(
    171            NotificationType::USER_SCRIPTS_UPDATED);
    172     }
    173   }
    174 
    175   TestInjection(false, false);
    176 }
    177 
    178 // ExtensionsLoadTest
    179 // Ensures that we can startup the browser with --load-extension and see them
    180 // run.
    181 
    182 class ExtensionsLoadTest : public ExtensionStartupTestBase {
    183  public:
    184   ExtensionsLoadTest() {
    185     enable_extensions_ = true;
    186     PathService::Get(chrome::DIR_TEST_DATA, &load_extension_);
    187     load_extension_ = load_extension_
    188         .AppendASCII("extensions")
    189         .AppendASCII("good")
    190         .AppendASCII("Extensions")
    191         .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
    192         .AppendASCII("1.0.0.0");
    193   }
    194 };
    195 
    196 IN_PROC_BROWSER_TEST_F(ExtensionsLoadTest, Test) {
    197   WaitForServicesToStart(1, true);
    198   TestInjection(true, true);
    199 }
    200