Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: chrome/browser/extensions/extension_browsertest.cc

Issue 150213: Add a ExtensionBrowserTest base class (Closed)
Patch Set: added timeouts fixed other tests Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 #include "chrome/browser/extensions/extension_browsertest.h"
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 2
5 #include "base/ref_counted.h" 3 #include "base/command_line.h"
4 #include "base/file_path.h"
5 #include "base/path_service.h"
6 #include "chrome/browser/browser.h" 6 #include "chrome/browser/browser.h"
7 #include "chrome/browser/browser_list.h"
8 #include "chrome/browser/renderer_host/render_view_host.h"
9 #include "chrome/browser/extensions/extension_host.h" 7 #include "chrome/browser/extensions/extension_host.h"
10 #include "chrome/browser/extensions/extension_process_manager.h"
11 #include "chrome/browser/extensions/extensions_service.h" 8 #include "chrome/browser/extensions/extensions_service.h"
12 #include "chrome/browser/extensions/test_extension_loader.h"
13 #include "chrome/browser/profile.h" 9 #include "chrome/browser/profile.h"
14 #include "chrome/browser/renderer_host/site_instance.h" 10 #include "chrome/common/chrome_switches.h"
15 #include "chrome/browser/views/extensions/extension_shelf.h"
16 #include "chrome/common/chrome_paths.h" 11 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h" 12 #include "chrome/common/notification_registrar.h"
18 #include "chrome/common/extensions/extension_error_reporter.h" 13 #include "chrome/common/notification_service.h"
19 #include "chrome/common/url_constants.h" 14 #include "chrome/common/notification_type.h"
20 #include "chrome/test/in_process_browser_test.h"
21 #include "chrome/test/ui_test_utils.h" 15 #include "chrome/test/ui_test_utils.h"
22 16
23 namespace { 17 namespace {
18 // Amount of time to wait to load an extension. This is purposely obscenely
19 // long because it will only get used in the case of failure and we want to
20 // minimize false positives.
21 static const int kTimeoutMs = 60 * 1000; // 1 minute
22 };
24 23
25 // How long to wait for the extension to put up a javascript alert before giving 24 // Base class for extension browser tests. Provides utilities for loading,
26 // up. 25 // unloading, and installing extensions.
27 const int kAlertTimeoutMs = 20000; 26 void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) {
27 // This enables DOM automation for tab contentses.
28 EnableDOMAutomation();
28 29
29 // The extensions we're using as our test case. 30 // This enables it for extension hosts.
30 const char* kGoodExtension1Id = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 31 ExtensionHost::EnableDOMAutomation();
31 const char* kGoodCrxId = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
32 32
33 }; // namespace 33 command_line->AppendSwitch(switches::kEnableExtensions);
34 34
35 // This class starts up an extension process and waits until it tries to put 35 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
36 // up a javascript alert. 36 test_data_dir_ = test_data_dir_.AppendASCII("extensions");
37 class MockExtensionHost : public ExtensionHost { 37 }
38 public: 38
39 MockExtensionHost(Extension* extension, const GURL& url, 39 bool ExtensionBrowserTest::LoadExtension(const FilePath& path) {
40 SiteInstance* instance) 40 ExtensionsService* service = browser()->profile()->GetExtensionsService();
41 : ExtensionHost(extension, instance, url), 41 size_t num_before = service->extensions()->size();
42 got_message_(false) { 42 registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
43 CreateRenderView(NULL); 43 NotificationService::AllSources());
44 MessageLoop::current()->PostDelayedTask(FROM_HERE, 44 service->LoadExtension(path);
45 new MessageLoop::QuitTask, kAlertTimeoutMs); 45 MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
46 ui_test_utils::RunMessageLoop(); 46 kTimeoutMs);
47 ui_test_utils::RunMessageLoop();
48 registrar_.Remove(this, NotificationType::EXTENSIONS_LOADED,
49 NotificationService::AllSources());
50 size_t num_after = service->extensions()->size();
51 if (num_after != (num_before + 1))
52 return false;
53
54 return WaitForExtensionHostsToLoad();
55 }
56
57 bool ExtensionBrowserTest::InstallExtension(const FilePath& path) {
58 ExtensionsService* service = browser()->profile()->GetExtensionsService();
59 service->set_show_extensions_prompts(false);
60 size_t num_before = service->extensions()->size();
61
62 registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
63 NotificationService::AllSources());
64 service->InstallExtension(path);
65 MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
66 kTimeoutMs);
67 ui_test_utils::RunMessageLoop();
68 registrar_.Remove(this, NotificationType::EXTENSION_INSTALLED,
69 NotificationService::AllSources());
70 size_t num_after = service->extensions()->size();
71 if (num_after != (num_before + 1))
72 return false;
73
74 return WaitForExtensionHostsToLoad();
75 }
76
77 void ExtensionBrowserTest::UninstallExtension(const std::string& extension_id) {
78 ExtensionsService* service = browser()->profile()->GetExtensionsService();
79 service->UninstallExtension(extension_id, false);
80 }
81
82 bool ExtensionBrowserTest::WaitForExtensionHostsToLoad() {
83 // Wait for all the extension hosts that exist to finish loading.
84 // NOTE: This assumes that the extension host list is not changing while
85 // this method is running.
86 ExtensionProcessManager* manager =
87 browser()->profile()->GetExtensionProcessManager();
88 base::Time start_time = base::Time::Now();
89 for (ExtensionProcessManager::const_iterator iter = manager->begin();
90 iter != manager->end(); ++iter) {
91 while (!(*iter)->did_stop_loading()) {
92 if ((base::Time::Now() - start_time).InMilliseconds() > kTimeoutMs)
93 return false;
94
95 MessageLoop::current()->PostDelayedTask(FROM_HERE,
96 new MessageLoop::QuitTask, 200);
97 ui_test_utils::RunMessageLoop();
98 }
47 } 99 }
48 100
49 virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher( 101 return true;
50 RenderViewHost* render_view_host) {
51 NOTREACHED();
52 return NULL;
53 }
54
55 bool got_message() { return got_message_; }
56 private:
57 virtual void RunJavaScriptMessage(
58 const std::wstring& message,
59 const std::wstring& default_prompt,
60 const GURL& frame_url,
61 const int flags,
62 IPC::Message* reply_msg,
63 bool* did_suppress_message) {
64 got_message_ = true;
65 MessageLoopForUI::current()->Quit();
66
67 // Call super, otherwise we'll leak reply_msg.
68 ExtensionHost::RunJavaScriptMessage(
69 message, default_prompt, frame_url, flags,
70 reply_msg, did_suppress_message);
71 }
72
73 bool got_message_;
74 };
75
76 class ExtensionViewTest : public InProcessBrowserTest {
77 public:
78 virtual void SetUp() {
79 // Initialize the error reporter here, otherwise BrowserMain will create it
80 // with the wrong MessageLoop.
81 ExtensionErrorReporter::Init(false);
82
83 InProcessBrowserTest::SetUp();
84 }
85 virtual void SetUpCommandLine(CommandLine* command_line) {
86 command_line->AppendSwitch(switches::kEnableExtensions);
87 }
88 };
89
90 // Tests that ExtensionView starts an extension process and runs the script
91 // contained in the extension's toolstrip.
92 // TODO(mpcomplete): http://crbug.com/15081 Disabled because it fails.
93 IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Toolstrip) {
94 // Get the path to our extension.
95 FilePath path;
96 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
97 path = path.AppendASCII("extensions")
98 .AppendASCII("good")
99 .AppendASCII("Extensions")
100 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
101 .AppendASCII("1.0.0.0");
102 ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check
103
104 // Wait for the extension to load and grab a pointer to it.
105 TestExtensionLoader loader(browser()->profile());
106 Extension* extension = loader.Load(kGoodExtension1Id, path);
107 ASSERT_TRUE(extension);
108 GURL url = Extension::GetResourceURL(extension->url(), "toolstrip1.html");
109
110 // Start the extension process and wait for it to show a javascript alert.
111 MockExtensionHost host(extension, url,
112 browser()->profile()->GetExtensionProcessManager()->
113 GetSiteInstanceForURL(url));
114 EXPECT_TRUE(host.got_message());
115 } 102 }
116 103
117 // Tests that the ExtensionShelf initializes properly, notices that 104 void ExtensionBrowserTest::Observe(NotificationType type,
118 // an extension loaded and has a view available, and then sets that up 105 const NotificationSource& source,
119 // properly. 106 const NotificationDetails& details) {
120 // TODO(mpcomplete): http://crbug.com/15081 Disabled because it fails. 107 switch (type.value) {
121 IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Shelf) { 108 case NotificationType::EXTENSION_INSTALLED:
122 // When initialized, there are no extension views and the preferred height 109 case NotificationType::EXTENSIONS_LOADED:
123 // should be zero. 110 MessageLoopForUI::current()->Quit();
124 scoped_ptr<ExtensionShelf> shelf(new ExtensionShelf(browser())); 111 break;
125 EXPECT_EQ(shelf->GetChildViewCount(), 0); 112 default:
126 EXPECT_EQ(shelf->GetPreferredSize().height(), 0); 113 NOTREACHED();
127 114 break;
128 // Get the path to our extension. 115 }
129 FilePath path;
130 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
131 path = path.AppendASCII("extensions")
132 .AppendASCII("good")
133 .AppendASCII("Extensions")
134 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
135 .AppendASCII("1.0.0.0");
136 ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check
137
138 // Wait for the extension to load and grab a pointer to it.
139 TestExtensionLoader loader(browser()->profile());
140 Extension* extension = loader.Load(kGoodExtension1Id, path);
141 ASSERT_TRUE(extension);
142
143 // There should now be two extension views and preferred height of the view
144 // should be non-zero.
145 EXPECT_EQ(shelf->GetChildViewCount(), 2);
146 EXPECT_NE(shelf->GetPreferredSize().height(), 0);
147 } 116 }
148
149 // Tests that installing and uninstalling extensions don't crash with an
150 // incognito window open.
151 // TODO(mpcomplete): http://crbug.com/14947 disabled because it crashes.
152 IN_PROC_BROWSER_TEST_F(ExtensionViewTest, DISABLED_Incognito) {
153 // Open an incognito window to the extensions management page. We just
154 // want to make sure that we don't crash while playing with extensions when
155 // this guy is around.
156 Browser::OpenURLOffTheRecord(browser()->profile(),
157 GURL(chrome::kChromeUIExtensionsURL));
158
159 // Get the path to our extension.
160 FilePath path;
161 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
162 path = path.AppendASCII("extensions").AppendASCII("good.crx");
163 ASSERT_TRUE(file_util::PathExists(path)); // sanity check
164
165 // Wait for the extension to load and grab a pointer to it.
166 TestExtensionLoader loader(browser()->profile());
167 Extension* extension = loader.Install(kGoodCrxId, path);
168 ASSERT_TRUE(extension);
169
170 // TODO(mpcomplete): wait for uninstall to complete?
171 browser()->profile()->GetExtensionsService()->
172 UninstallExtension(kGoodCrxId, false);
173 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_browsertest.h ('k') | chrome/browser/extensions/extension_browsertests_misc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698