• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ExtensionStartupTestBase()30   ExtensionStartupTestBase() : enable_extensions_(false) {
31     num_expected_extensions_ = 3;
32   }
33 
34  protected:
35   // InProcessBrowserTest
SetUpCommandLine(CommandLine * command_line)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 
TearDown()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 
WaitForServicesToStart(int num_expected_extensions,bool expect_extensions_enabled)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 
TestInjection(bool expect_css,bool expect_script)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:
ExtensionsStartupTest()143   ExtensionsStartupTest() {
144     enable_extensions_ = true;
145   }
146 };
147 
IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest,Test)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.
IN_PROC_BROWSER_TEST_F(ExtensionsStartupTest,MAYBE_NoFileAccess)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:
ExtensionsLoadTest()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 
IN_PROC_BROWSER_TEST_F(ExtensionsLoadTest,Test)196 IN_PROC_BROWSER_TEST_F(ExtensionsLoadTest, Test) {
197   WaitForServicesToStart(1, true);
198   TestInjection(true, true);
199 }
200