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