summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-25 23:23:27 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-25 23:23:27 +0000
commit781dbd7d16db4fbf7073f1e389120e052d2831aa (patch)
tree91ca96778bef46bbd639d100a53f645dfb34497f
parent30fdaad8397236d319832dd33fe3fd72e693693e (diff)
downloadchromium_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.cc49
-rw-r--r--chrome/browser/automation/automation_provider_observers.h21
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc8
-rw-r--r--chrome/browser/automation/testing_automation_provider.h4
-rw-r--r--chrome/test/webdriver/automation.cc8
-rw-r--r--chrome/test/webdriver/automation.h3
-rw-r--r--chrome/test/webdriver/commands/webdriver_command.cc3
-rw-r--r--chrome/test/webdriver/session.cc11
-rw-r--r--chrome/test/webdriver/session.h3
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_; }