summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_uitest.cc
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 03:52:30 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 03:52:30 +0000
commit6e67b73e35b3cd2946b86bb2e9766cf59026247c (patch)
tree6fd9864a011f9a6caa897dd68a2604cd4d0c9e1a /chrome/browser/extensions/extension_uitest.cc
parent2e49fc3cceaa87f1472fae156271e594cfa140d3 (diff)
downloadchromium_src-6e67b73e35b3cd2946b86bb2e9766cf59026247c.zip
chromium_src-6e67b73e35b3cd2946b86bb2e9766cf59026247c.tar.gz
chromium_src-6e67b73e35b3cd2946b86bb2e9766cf59026247c.tar.bz2
Add support to the automation provider to test sending browser
events to extensions. Implements an initial test that send all known window, tab, page action, and bookmark events and makes sure the extension received them. Original review: http://codereview.chromium.org/119325 Review URL: http://codereview.chromium.org/123010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18148 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_uitest.cc')
-rw-r--r--chrome/browser/extensions/extension_uitest.cc169
1 files changed, 169 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_uitest.cc b/chrome/browser/extensions/extension_uitest.cc
index 102bbac..9180966 100644
--- a/chrome/browser/extensions/extension_uitest.cc
+++ b/chrome/browser/extensions/extension_uitest.cc
@@ -20,6 +20,8 @@ static const char kTestDirectorySimpleApiCall[] =
"extensions/uitest/simple_api_call";
static const char kTestDirectoryRoundtripApiCall[] =
"extensions/uitest/roundtrip_api_call";
+static const char kTestDirectoryBrowserEvent[] =
+ "extensions/uitest/event_sink";
// Base class to test extensions almost end-to-end by including browser
// startup, manifest parsing, and the actual process model in the
@@ -279,4 +281,171 @@ TEST_F(RoundtripApiCallExtensionTest, RunTest) {
}
#endif // defined(OS_WIN)
+// This proxy is specific to BrowserEventExtensionTest.
+class BrowserEventAutomationProxy : public MultiMessageAutomationProxy {
+ public:
+ explicit BrowserEventAutomationProxy(int execution_timeout)
+ : MultiMessageAutomationProxy(execution_timeout),
+ tab_(NULL) {
+ }
+
+ // Must set before initiating test.
+ TabProxy* tab_;
+
+ // Counts the number of times we got a given event.
+ std::map<std::string, int> event_count_;
+
+ // Array containing the names of the events to fire to the extension.
+ static const char* event_names_[];
+
+ protected:
+ // Process a message received from the test extension.
+ virtual void HandleMessageFromChrome();
+
+ // Fire an event of the given name to the test extension.
+ void FireEvent(const char* event_name);
+};
+
+const char* BrowserEventAutomationProxy::event_names_[] = {
+ // Window events.
+ "window-created",
+ "window-removed",
+ "window-focus-changed",
+
+ // Tab events.
+ "tab-created",
+ "tab-updated",
+ "tab-moved",
+ "tab-selection-changed",
+ "tab-attached",
+ "tab-detached",
+ "tab-removed",
+
+ // Page action events.
+ "page-action-executed",
+
+ // Bookmark events.
+ "bookmark-added",
+ "bookmark-removed",
+ "bookmark-changed",
+ "bookmark-moved",
+ "bookmark-children-reordered",
+};
+
+void BrowserEventAutomationProxy::HandleMessageFromChrome() {
+ namespace keys = extension_automation_constants;
+ ASSERT_TRUE(tab_ != NULL);
+
+ std::string message(message());
+ std::string origin(origin());
+ std::string target(target());
+
+ ASSERT_TRUE(message.length() > 0);
+ ASSERT_STREQ(keys::kAutomationOrigin, origin.c_str());
+
+ if (target == keys::kAutomationRequestTarget) {
+ // This should be a request for the current window. We don't need to
+ // respond, as this is used only as an indication that the extension
+ // page is now loaded.
+ scoped_ptr<Value> message_value(JSONReader::Read(message, false));
+ ASSERT_TRUE(message_value->IsType(Value::TYPE_DICTIONARY));
+ DictionaryValue* message_dict =
+ reinterpret_cast<DictionaryValue*>(message_value.get());
+
+ std::string name;
+ message_dict->GetString(keys::kAutomationNameKey, &name);
+ ASSERT_STREQ(name.c_str(), "GetCurrentWindow");
+
+ // Send an OpenChannelToExtension message to chrome. Note: the JSON
+ // reader expects quoted property keys.
+ tab_->HandleMessageFromExternalHost(
+ "{\"rqid\":0, \"extid\": \"88884444789ABCDEF0123456789ABCDEF0123456\","
+ " \"connid\": 1}",
+ keys::kAutomationOrigin,
+ keys::kAutomationPortRequestTarget);
+ } else if (target == keys::kAutomationPortResponseTarget) {
+ // This is a response to the open channel request. This means we know
+ // that the port is ready to send us messages. Fire all the events now.
+ for (int i = 0; i < arraysize(event_names_); ++i) {
+ FireEvent(event_names_[i]);
+ }
+ } else if (target == keys::kAutomationPortRequestTarget) {
+ // This is the test extension calling us back. Make sure its telling
+ // us that it received an event. We do this by checking to see if the
+ // message is a simple string of one of the event names that is fired.
+ //
+ // There is a special message "ACK" which means that the extension
+ // received the port connection. This is not an event response and
+ // should happen before all events.
+ scoped_ptr<Value> message_value(JSONReader::Read(message, false));
+ ASSERT_TRUE(message_value->IsType(Value::TYPE_DICTIONARY));
+ DictionaryValue* message_dict =
+ reinterpret_cast<DictionaryValue*>(message_value.get());
+
+ std::string event_name;
+ message_dict->GetString(L"data", &event_name);
+ if (event_name == "\"ACK\"") {
+ ASSERT_EQ(0, event_count_.size());
+ } else {
+ ++event_count_[event_name];
+ }
+ }
+}
+
+void BrowserEventAutomationProxy::FireEvent(const char* event_name) {
+ namespace keys = extension_automation_constants;
+
+ // Build the event message to send to the extension. The only important
+ // part is the name, as the payload is not used by the test extension.
+ std::string message;
+ message += "[\"";
+ message += event_name;
+ message += "\", \"[]\"]";
+
+ tab_->HandleMessageFromExternalHost(
+ message,
+ keys::kAutomationOrigin,
+ keys::kAutomationBrowserEventRequestTarget);
+}
+
+class BrowserEventExtensionTest
+ : public ExtensionUITest<
+ CustomAutomationProxyTest<BrowserEventAutomationProxy>> {
+ public:
+ BrowserEventExtensionTest()
+ : ExtensionUITest<
+ CustomAutomationProxyTest<
+ BrowserEventAutomationProxy> >(kTestDirectoryBrowserEvent) {
+ }
+
+ void DoAdditionalPreNavigateSetup(TabProxy* tab) {
+ BrowserEventAutomationProxy* proxy =
+ static_cast<BrowserEventAutomationProxy*>(automation());
+ proxy->tab_ = tab;
+ }
+
+ private:
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserEventExtensionTest);
+};
+
+// TODO(port) Should become portable once
+// ExternalTabMessageLoop is ported.
+#if defined(OS_WIN)
+TEST_F(BrowserEventExtensionTest, RunTest) {
+ TestWithURL(GURL(
+ "chrome-extension://88884444789ABCDEF0123456789ABCDEF0123456/test.html"));
+ BrowserEventAutomationProxy* proxy =
+ static_cast<BrowserEventAutomationProxy*>(automation());
+
+ EXPECT_EQ(arraysize(BrowserEventAutomationProxy::event_names_),
+ proxy->event_count_.size());
+ for (std::map<std::string, int>::iterator i = proxy->event_count_.begin();
+ i != proxy->event_count_.end(); ++i) {
+ const std::pair<std::string, int>& value = *i;
+ ASSERT_EQ(1, value.second);
+ }
+}
+#endif // defined(OS_WIN)
+
} // namespace