1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#include "chrome/browser/extensions/extension_browsertest.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/location_bar.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_error_reporter.h"
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/ui_test_utils.h"
namespace {
// Amount of time to wait to load an extension. This is purposely obscenely
// long because it will only get used in the case of failure and we want to
// minimize false positives.
static const int kTimeoutMs = 60 * 1000; // 1 minute
};
// Base class for extension browser tests. Provides utilities for loading,
// unloading, and installing extensions.
void ExtensionBrowserTest::SetUpCommandLine(CommandLine* command_line) {
// This enables DOM automation for tab contentses.
EnableDOMAutomation();
// This enables it for extension hosts.
ExtensionHost::EnableDOMAutomation();
command_line->AppendSwitch(switches::kEnableExtensions);
PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_);
test_data_dir_ = test_data_dir_.AppendASCII("extensions");
}
bool ExtensionBrowserTest::LoadExtension(const FilePath& path) {
ExtensionsService* service = browser()->profile()->GetExtensionsService();
size_t num_before = service->extensions()->size();
registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
NotificationService::AllSources());
service->LoadExtension(path);
MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
kTimeoutMs);
ui_test_utils::RunMessageLoop();
registrar_.Remove(this, NotificationType::EXTENSIONS_LOADED,
NotificationService::AllSources());
size_t num_after = service->extensions()->size();
if (num_after != (num_before + 1))
return false;
return WaitForExtensionHostsToLoad();
}
bool ExtensionBrowserTest::InstallExtension(const FilePath& path) {
ExtensionsService* service = browser()->profile()->GetExtensionsService();
service->set_show_extensions_prompts(false);
size_t num_before = service->extensions()->size();
registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
NotificationService::AllSources());
service->InstallExtension(path);
MessageLoop::current()->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
kTimeoutMs);
ui_test_utils::RunMessageLoop();
registrar_.Remove(this, NotificationType::EXTENSIONS_LOADED,
NotificationService::AllSources());
size_t num_after = service->extensions()->size();
if (num_after != (num_before + 1)) {
std::cout << "Num extensions before: " << IntToString(num_before) << " "
<< "num after: " << IntToString(num_after) << " "
<< "Installed extensions follow:\n";
for (size_t i = 0; i < service->extensions()->size(); ++i)
std::cout << " " << service->extensions()->at(i)->id() << "\n";
std::cout << "Errors follow:\n";
const std::vector<std::string>* errors =
ExtensionErrorReporter::GetInstance()->GetErrors();
for (std::vector<std::string>::const_iterator iter = errors->begin();
iter != errors->end(); ++iter) {
std::cout << *iter << "\n";
}
return false;
}
return WaitForExtensionHostsToLoad();
}
void ExtensionBrowserTest::UninstallExtension(const std::string& extension_id) {
ExtensionsService* service = browser()->profile()->GetExtensionsService();
service->UninstallExtension(extension_id, false);
}
bool ExtensionBrowserTest::WaitForPageActionVisibilityChangeTo(
int count) {
base::Time start_time = base::Time::Now();
while (true) {
LocationBarTesting* loc_bar =
browser()->window()->GetLocationBar()->GetLocationBarForTesting();
int visible = loc_bar->PageActionVisibleCount();
if (visible == count)
return true;
if ((base::Time::Now() - start_time).InMilliseconds() > kTimeoutMs)
return false;
std::cout << "Timed out waiting for page actions to become visible."
<< "Currently visible page actions: " << IntToString(visible);
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask, 200);
ui_test_utils::RunMessageLoop();
}
}
bool ExtensionBrowserTest::WaitForExtensionHostsToLoad() {
// Wait for all the extension hosts that exist to finish loading.
// NOTE: This assumes that the extension host list is not changing while
// this method is running.
ExtensionProcessManager* manager =
browser()->profile()->GetExtensionProcessManager();
base::Time start_time = base::Time::Now();
for (ExtensionProcessManager::const_iterator iter = manager->begin();
iter != manager->end(); ++iter) {
while (!(*iter)->did_stop_loading()) {
if ((base::Time::Now() - start_time).InMilliseconds() > kTimeoutMs) {
std::cout << "Extension host did not load for URL: "
<< (*iter)->GetURL().spec();
return false;
}
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new MessageLoop::QuitTask, 200);
ui_test_utils::RunMessageLoop();
}
}
return true;
}
void ExtensionBrowserTest::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
switch (type.value) {
case NotificationType::EXTENSIONS_LOADED:
std::cout << "Got EXTENSION_LOADED notification.\n";
MessageLoopForUI::current()->Quit();
break;
default:
NOTREACHED();
break;
}
}
|