diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-16 23:13:55 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-16 23:13:55 +0000 |
commit | a902489dc0a391b0bfa92b8a172aa6369b568436 (patch) | |
tree | df5210dd269a1b5ba952a66f40e1740592da1cf6 /chrome/browser/extensions | |
parent | 560541ea404af23c1e91f0ef83b4ed11022a84c7 (diff) | |
download | chromium_src-a902489dc0a391b0bfa92b8a172aa6369b568436.zip chromium_src-a902489dc0a391b0bfa92b8a172aa6369b568436.tar.gz chromium_src-a902489dc0a391b0bfa92b8a172aa6369b568436.tar.bz2 |
submitted on behalf of rogerta (Roger Tawa).
Original issue: http://codereview.chromium.org/119325
r=rafaelw,Jói,stoyan,aa
Review URL: http://codereview.chromium.org/125206
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18555 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/extension_uitest.cc | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_uitest.cc b/chrome/browser/extensions/extension_uitest.cc index 4f5d870..359ba9a 100644 --- a/chrome/browser/extensions/extension_uitest.cc +++ b/chrome/browser/extensions/extension_uitest.cc @@ -9,6 +9,7 @@ #include "base/values.h" #include "chrome/browser/automation/extension_automation_constants.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension.h" #include "chrome/test/automation/automation_proxy_uitest.h" #include "chrome/test/automation/tab_proxy.h" #include "chrome/test/ui/ui_test.h" @@ -20,6 +21,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 @@ -280,4 +283,179 @@ 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. See the comment in + // TEST_F(BrowserEventExtensionTest, RunTest) to understand where the + // extension Id comes from. + tab_->HandleMessageFromExternalHost( + "{\"rqid\":0, \"extid\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"," + " \"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) { + // The extension for this test does not specify a "key" property in its + // manifest file. Therefore, the extension system will automatically assign + // it an Id. To make this test consistent and non-flaky, the genetated Id + // counter is reset before the test so that we can hardcode the first Id + // that will be generated. + Extension::ResetGeneratedIdCounter(); + TestWithURL(GURL( + "chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/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 |