diff options
author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-25 23:23:27 +0000 |
---|---|---|
committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-25 23:23:27 +0000 |
commit | 781dbd7d16db4fbf7073f1e389120e052d2831aa (patch) | |
tree | 91ca96778bef46bbd639d100a53f645dfb34497f | |
parent | 30fdaad8397236d319832dd33fe3fd72e693693e (diff) | |
download | chromium_src-781dbd7d16db4fbf7073f1e389120e052d2831aa.zip chromium_src-781dbd7d16db4fbf7073f1e389120e052d2831aa.tar.gz chromium_src-781dbd7d16db4fbf7073f1e389120e052d2831aa.tar.bz2 |
In ChromeDriver, wait for all tabs to stop loading before executing a session command.
This is required by the WebDriver spec.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6580040
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76113 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.cc | 49 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_observers.h | 21 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 8 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 4 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.cc | 8 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.h | 3 | ||||
-rw-r--r-- | chrome/test/webdriver/commands/webdriver_command.cc | 3 | ||||
-rw-r--r-- | chrome/test/webdriver/session.cc | 11 | ||||
-rw-r--r-- | chrome/test/webdriver/session.h | 3 |
9 files changed, 110 insertions, 0 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index 4a4ecab..681a287 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -1972,6 +1972,55 @@ void InputEventAckNotificationObserver::Observe( } } +AllTabsStoppedLoadingObserver::AllTabsStoppedLoadingObserver( + AutomationProvider* automation, + IPC::Message* reply_message) + : automation_(automation->AsWeakPtr()), + reply_message_(reply_message) { + registrar_.Add(this, NotificationType::LOAD_STOP, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::TAB_CONTENTS_DISCONNECTED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::TAB_CONTENTS_SWAPPED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::TAB_CLOSED, + NotificationService::AllSources()); + CheckIfStopped(); +} + +AllTabsStoppedLoadingObserver::~AllTabsStoppedLoadingObserver() {} + +void AllTabsStoppedLoadingObserver::Observe( + NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + CheckIfStopped(); +} + +void AllTabsStoppedLoadingObserver::CheckIfStopped() { + bool done_loading = true; + BrowserList::const_iterator iter = BrowserList::begin(); + for (; iter != BrowserList::end(); ++iter) { + Browser* browser = *iter; + for (int i = 0; i < browser->tab_count(); ++i) { + TabContents* tab = browser->GetTabContentsAt(i); + if (tab->is_loading()) { + done_loading = false; + break; + } + } + if (!done_loading) + break; + } + if (done_loading) { + AutomationJSONReply(automation_, + reply_message_.release()).SendSuccess(NULL); + delete this; + } +} + NewTabObserver::NewTabObserver(AutomationProvider* automation, IPC::Message* reply_message) : automation_(automation->AsWeakPtr()), diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h index 0ffc85f..45620c5 100644 --- a/chrome/browser/automation/automation_provider_observers.h +++ b/chrome/browser/automation/automation_provider_observers.h @@ -1073,6 +1073,27 @@ class InputEventAckNotificationObserver : public NotificationObserver { DISALLOW_COPY_AND_ASSIGN(InputEventAckNotificationObserver); }; +// Allows the automation provider to wait for all tabs to stop loading. +class AllTabsStoppedLoadingObserver : public NotificationObserver { + public: + // Registers for notifications and checks to see if all tabs have stopped. + AllTabsStoppedLoadingObserver(AutomationProvider* automation, + IPC::Message* reply_message); + virtual ~AllTabsStoppedLoadingObserver(); + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + private: + void CheckIfStopped(); + NotificationRegistrar registrar_; + base::WeakPtr<AutomationProvider> automation_; + scoped_ptr<IPC::Message> reply_message_; + + DISALLOW_COPY_AND_ASSIGN(AllTabsStoppedLoadingObserver); +}; + // Observer used to listen for new tab creation to complete. class NewTabObserver : public NotificationObserver { public: diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index d56769c..1833006 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -2090,6 +2090,8 @@ void TestingAutomationProvider::SendJSONRequest(int handle, // Map json commands to their handlers. std::map<std::string, JsonHandler> handler_map; + handler_map["WaitForAllTabsToStopLoading"] = + &TestingAutomationProvider::WaitForAllTabsToStopLoading; #if defined(OS_CHROMEOS) handler_map["LoginAsGuest"] = &TestingAutomationProvider::LoginAsGuest; handler_map["Login"] = &TestingAutomationProvider::Login; @@ -4623,6 +4625,12 @@ void TestingAutomationProvider::SendKeyEventToActiveTab( ForwardKeyboardEvent(event); } +void TestingAutomationProvider::WaitForAllTabsToStopLoading( + DictionaryValue* args, + IPC::Message* reply_message) { + new AllTabsStoppedLoadingObserver(this, reply_message); +} + void TestingAutomationProvider::WaitForTabCountToBecome( int browser_handle, int target_tab_count, diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index d840d74..56034f6 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -772,6 +772,10 @@ class TestingAutomationProvider : public AutomationProvider, DictionaryValue* args, IPC::Message* reply_message); + // Waits for all tabs to stop loading. + void WaitForAllTabsToStopLoading(DictionaryValue* args, + IPC::Message* reply_message); + #if defined(OS_CHROMEOS) void LoginAsGuest(DictionaryValue* args, IPC::Message* reply_message); diff --git a/chrome/test/webdriver/automation.cc b/chrome/test/webdriver/automation.cc index d3ba016..f40d8e9 100644 --- a/chrome/test/webdriver/automation.cc +++ b/chrome/test/webdriver/automation.cc @@ -434,6 +434,14 @@ void Automation::GetVersion(std::string* version) { *version = launcher_->automation()->server_version(); } +void Automation::WaitForAllTabsToStopLoading(bool* success) { + DictionaryValue dict; + dict.SetString("command", "WaitForAllTabsToStopLoading"); + std::string request, reply; + base::JSONWriter::Write(&dict, false, &request); + *success = launcher_->automation()->SendJSONRequest(request, &reply); +} + TabProxy* Automation::GetTabById(int tab_id) { TabIdMap::const_iterator iter = tab_id_map_.find(tab_id); if (iter != tab_id_map_.end()) { diff --git a/chrome/test/webdriver/automation.h b/chrome/test/webdriver/automation.h index 0bbdb27..0be141a 100644 --- a/chrome/test/webdriver/automation.h +++ b/chrome/test/webdriver/automation.h @@ -109,6 +109,9 @@ class Automation { // Gets the version of the runing browser. void GetVersion(std::string* version); + // Waits for all tabs to stop loading. + void WaitForAllTabsToStopLoading(bool* success); + private: typedef std::map<int, scoped_refptr<TabProxy> > TabIdMap; TabProxy* GetTabById(int tab_id); diff --git a/chrome/test/webdriver/commands/webdriver_command.cc b/chrome/test/webdriver/commands/webdriver_command.cc index efa0f8a..8d038f1 100644 --- a/chrome/test/webdriver/commands/webdriver_command.cc +++ b/chrome/test/webdriver/commands/webdriver_command.cc @@ -30,6 +30,9 @@ bool WebDriverCommand::Init(Response* const response) { kSessionNotFound); return false; } + if (!session_->WaitForAllTabsToStopLoading()) { + LOG(WARNING) << "Failed to wait for all tabs to stop loading"; + } response->SetField("sessionId", Value::CreateStringValue(session_id)); return true; diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc index c8d9054..400c7eb 100644 --- a/chrome/test/webdriver/session.cc +++ b/chrome/test/webdriver/session.cc @@ -549,6 +549,17 @@ ErrorCode Session::GetElementLocationInView( return kSuccess; } +bool Session::WaitForAllTabsToStopLoading() { + if (!automation_.get()) + return true; + bool success = false; + RunSessionTask(NewRunnableMethod( + automation_.get(), + &Automation::WaitForAllTabsToStopLoading, + &success)); + return success; +} + void Session::RunSessionTask(Task* task) { base::WaitableEvent done_event(false, false); thread_.message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod( diff --git a/chrome/test/webdriver/session.h b/chrome/test/webdriver/session.h index d48444f..222823c 100644 --- a/chrome/test/webdriver/session.h +++ b/chrome/test/webdriver/session.h @@ -144,6 +144,9 @@ class Session { ErrorCode GetElementLocationInView( const WebElementId& element, int* x, int* y); + // Waits for all tabs to stop loading. Returns true on success. + bool WaitForAllTabsToStopLoading(); + inline const std::string& id() const { return id_; } inline int implicit_wait() const { return implicit_wait_; } |