diff options
-rw-r--r-- | chrome/browser/automation/automation_event_observer.cc | 63 | ||||
-rw-r--r-- | chrome/browser/automation/automation_event_observer.h | 56 | ||||
-rw-r--r-- | chrome/browser/automation/automation_event_queue.cc | 127 | ||||
-rw-r--r-- | chrome/browser/automation/automation_event_queue.h | 76 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 80 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 43 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 4 | ||||
-rw-r--r-- | chrome/test/data/apptest/basic.html | 74 | ||||
-rw-r--r-- | chrome/test/functional/PYAUTO_TESTS | 1 | ||||
-rw-r--r-- | chrome/test/functional/apptest.py | 38 | ||||
-rwxr-xr-x | chrome/test/pyautolib/pyauto.py | 86 |
11 files changed, 648 insertions, 0 deletions
diff --git a/chrome/browser/automation/automation_event_observer.cc b/chrome/browser/automation/automation_event_observer.cc new file mode 100644 index 0000000..feadd29 --- /dev/null +++ b/chrome/browser/automation/automation_event_observer.cc @@ -0,0 +1,63 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/logging.h" +#include "chrome/browser/automation/automation_event_observer.h" +#include "chrome/browser/automation/automation_event_queue.h" +#include "chrome/browser/automation/automation_provider.h" +#include "chrome/browser/automation/automation_provider_json.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" + +AutomationEventObserver::AutomationEventObserver( + AutomationEventQueue* event_queue) + : event_queue_(event_queue), observer_id_(-1) { + DCHECK(event_queue_ != NULL); +} + +AutomationEventObserver::~AutomationEventObserver() {} + +void AutomationEventObserver::NotifyEvent(DictionaryValue* value) { + if (event_queue_) { + event_queue_->NotifyEvent( + new AutomationEventQueue::AutomationEvent( + GetId(), value)); + } +} + +void AutomationEventObserver::Init(int observer_id) { + if (observer_id_ < 0) { + observer_id_ = observer_id; + } +} + +int AutomationEventObserver::GetId() const { + return observer_id_; +} + +DomRaisedEventObserver::DomRaisedEventObserver( + AutomationEventQueue* event_queue, const std::string& event_name) + : AutomationEventObserver(event_queue), event_name_(event_name) {} + +DomRaisedEventObserver::~DomRaisedEventObserver() {} + +void DomRaisedEventObserver::OnDomOperationCompleted(const std::string& json) { + DictionaryValue* dict = new DictionaryValue; + dict->SetString("type", "raised"); + dict->SetString("name", json); + dict->SetInteger("observer_id", GetId()); + NotifyEvent(dict); +} + +void DomRaisedEventObserver::OnModalDialogShown() { + DictionaryValue* dict = new DictionaryValue; + dict->SetString("error", "Blocked by modal dialogue"); + NotifyEvent(dict); +} + +void DomRaisedEventObserver::OnJavascriptBlocked() { + DictionaryValue* dict = new DictionaryValue; + dict->SetString("error", "Javascript execution was blocked"); + NotifyEvent(dict); +} diff --git a/chrome/browser/automation/automation_event_observer.h b/chrome/browser/automation/automation_event_observer.h new file mode 100644 index 0000000..3915648 --- /dev/null +++ b/chrome/browser/automation/automation_event_observer.h @@ -0,0 +1,56 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_OBSERVER_H_ +#define CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_OBSERVER_H_ + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/automation/automation_provider_observers.h" +#include "chrome/browser/automation/automation_event_queue.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" + +// AutomationEventObserver watches for a specific event, and pushes an +// AutomationEvent into the AutomationEventQueue for each occurance. +class AutomationEventObserver { + public: + explicit AutomationEventObserver(AutomationEventQueue* event_queue); + virtual ~AutomationEventObserver(); + + void Init(int observer_id); + void NotifyEvent(DictionaryValue* value); + int GetId() const; + + private: + AutomationEventQueue* event_queue_; + int observer_id_; + + DISALLOW_COPY_AND_ASSIGN(AutomationEventObserver); +}; + +// AutomationEventObserver implementation that listens for explicitly raised +// events. A webpage currently raises events by calling: +// window.domAutomationController.setAutomationId(42); // Any integer works. +// window.domAutomationController("EVENT_NAME"); +// TODO(craigdh): This method is a temporary hack. +class DomRaisedEventObserver + : public AutomationEventObserver, public DomOperationObserver { + public: + DomRaisedEventObserver(AutomationEventQueue* event_queue, + const std::string& event_name); + virtual ~DomRaisedEventObserver(); + + virtual void OnDomOperationCompleted(const std::string& json) OVERRIDE; + virtual void OnModalDialogShown() OVERRIDE; + virtual void OnJavascriptBlocked() OVERRIDE; + + private: + std::string event_name_; + content::NotificationRegistrar registrar_; + + DISALLOW_COPY_AND_ASSIGN(DomRaisedEventObserver); +}; + +#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_OBSERVER_H_ diff --git a/chrome/browser/automation/automation_event_queue.cc b/chrome/browser/automation/automation_event_queue.cc new file mode 100644 index 0000000..fd4f792 --- /dev/null +++ b/chrome/browser/automation/automation_event_queue.cc @@ -0,0 +1,127 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <algorithm> + +#include "chrome/browser/automation/automation_event_observer.h" +#include "chrome/browser/automation/automation_event_queue.h" +#include "chrome/browser/automation/automation_provider_json.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_types.h" + +AutomationEventQueue::CompareObserverId::CompareObserverId(int id) : id_(id) {} + +bool AutomationEventQueue::CompareObserverId::operator()( + AutomationEvent* event) const { + return event->GetId() < 0 || event->GetId() == id_; +} + +AutomationEventQueue::AutomationEventQueue() + : observer_id_count_(0), + wait_automation_reply_(NULL), + wait_observer_id_(-1) {} + +AutomationEventQueue::~AutomationEventQueue() { + Clear(); +} + +AutomationEventQueue::AutomationEvent::AutomationEvent( + int observer_id, DictionaryValue* event_value) + : observer_id_(observer_id), event_value_(event_value) {} + +void AutomationEventQueue::GetNextEvent(AutomationJSONReply* reply, + int observer_id, + bool blocking) { + wait_automation_reply_.reset(reply); + wait_observer_id_ = observer_id; + if (!CheckReturnEvent() && !blocking && wait_automation_reply_.get()) { + wait_automation_reply_->SendSuccess(NULL); + wait_automation_reply_.reset(); + } +} + +void AutomationEventQueue::Clear() { + ClearObservers(); + ClearEvents(); +} + +bool AutomationEventQueue::IsEmpty() const { + return event_queue_.empty(); +} + +AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent() { + if (event_queue_.empty()) { + return NULL; + } + AutomationEvent* event = event_queue_.back(); + event_queue_.pop_back(); + return event; +} + +AutomationEventQueue::AutomationEvent* AutomationEventQueue::PopEvent( + int observer_id) { + AutomationEvent* event = NULL; + std::list<AutomationEvent*>::reverse_iterator it = + std::find_if(event_queue_.rbegin(), event_queue_.rend(), + CompareObserverId(observer_id)); + if (it != event_queue_.rend()) { + event = *it; + event_queue_.remove(event); + } + return event; +} + +void AutomationEventQueue::NotifyEvent( + AutomationEventQueue::AutomationEvent* event) { + event_queue_.push_front(event); + CheckReturnEvent(); +} + +int AutomationEventQueue::AddObserver(AutomationEventObserver* observer) { + int id = observer_id_count_++; + observer->Init(id); + observers_[id] = observer; + return id; +} + +bool AutomationEventQueue::RemoveObserver(int observer_id) { + if (observers_.find(observer_id) != observers_.end()) { + delete observers_[observer_id]; + observers_.erase(observer_id); + return true; + } + return false; +} + +void AutomationEventQueue::ClearObservers() { + std::map<int, AutomationEventObserver*>::iterator it; + for (it = observers_.begin(); it != observers_.end(); it++) { + delete it->second; + } + observers_.clear(); +} + +void AutomationEventQueue::ClearEvents() { + std::list<AutomationEvent*>::iterator it; + for (it = event_queue_.begin(); it != event_queue_.end(); it++) { + delete *it; + } + event_queue_.clear(); +} + +bool AutomationEventQueue::CheckReturnEvent() { + if (wait_automation_reply_.get()) { + AutomationEventQueue::AutomationEvent* event = wait_observer_id_ < 0 ? + PopEvent() : + PopEvent(wait_observer_id_); + if (event) { + wait_automation_reply_->SendSuccess(event->GetValue()); + wait_automation_reply_.reset(); + wait_observer_id_ = -1; + delete event; + return true; + } + } + return false; +} diff --git a/chrome/browser/automation/automation_event_queue.h b/chrome/browser/automation/automation_event_queue.h new file mode 100644 index 0000000..1633e8a --- /dev/null +++ b/chrome/browser/automation/automation_event_queue.h @@ -0,0 +1,76 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_QUEUE_H_ +#define CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_QUEUE_H_ + +#include <list> +#include <map> + +#include "base/memory/scoped_ptr.h" +#include "base/values.h" + +class AutomationEventObserver; +class AutomationJSONReply; + +// AutomationEventQueue maintains a queue of unhandled automation events. +class AutomationEventQueue { + public: + AutomationEventQueue(); + virtual ~AutomationEventQueue(); + + // AutomationEvent stores return data dictionay for a single event. + class AutomationEvent { + public: + AutomationEvent(int observer_id, DictionaryValue* event_value); + virtual ~AutomationEvent() {} + + int GetId() const { return observer_id_; } + DictionaryValue* GetValue() { return event_value_.get(); } + DictionaryValue* ReleaseValue() { return event_value_.release(); } + + private: + int observer_id_; + scoped_ptr<DictionaryValue> event_value_; + }; + + void GetNextEvent(AutomationJSONReply* reply, + int observer_id, + bool blocking); + void NotifyEvent(AutomationEvent* event); + void Clear(); + bool IsEmpty() const; + AutomationEvent* PopEvent(); + AutomationEvent* PopEvent(int observer_id); + + int AddObserver(AutomationEventObserver* observer); + bool RemoveObserver(int observer_id); + + private: + class CompareObserverId { + public: + explicit CompareObserverId(int id); + bool operator()(AutomationEvent* event) const; + + private: + int id_; + }; + + void ClearEvents(); + void ClearObservers(); + bool CheckReturnEvent(); + + std::list<AutomationEvent*> event_queue_; + std::map<int, AutomationEventObserver*> observers_; + int observer_id_count_; + + // These store the automation reply data when GetNextEvent is called with no + // matching event in the queue and blocking is requested. + scoped_ptr<AutomationJSONReply> wait_automation_reply_; + int wait_observer_id_; + + DISALLOW_COPY_AND_ASSIGN(AutomationEventQueue); +}; + +#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_EVENT_QUEUE_H_ diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 11f239a..ba0df97 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -2316,6 +2316,14 @@ void TestingAutomationProvider::SendJSONRequest(int handle, handler_map["SetPrefs"] = &TestingAutomationProvider::SetPrefs; handler_map["ExecuteJavascript"] = &TestingAutomationProvider::ExecuteJavascriptJSON; + handler_map["AddDomRaisedEventObserver"] = + &TestingAutomationProvider::AddDomRaisedEventObserver; + handler_map["RemoveEventObserver"] = + &TestingAutomationProvider::RemoveEventObserver; + handler_map["GetNextEvent"] = + &TestingAutomationProvider::GetNextEvent; + handler_map["ClearEventQueue"] = + &TestingAutomationProvider::ClearEventQueue; handler_map["ExecuteJavascriptInRenderView"] = &TestingAutomationProvider::ExecuteJavascriptInRenderView; handler_map["GoForward"] = @@ -6445,6 +6453,78 @@ void TestingAutomationProvider::ExecuteJavascriptInRenderView( rvh); } +void TestingAutomationProvider::AddDomRaisedEventObserver( + DictionaryValue* args, + IPC::Message* reply_message) { + if (SendErrorIfModalDialogActive(this, reply_message)) + return; + + AutomationJSONReply reply(this, reply_message); + std::string event_name; + if (!args->GetString("event_name", &event_name)) { + reply.SendError("'event_name' missing or invalid"); + return; + } + + if (!automation_event_queue_.get()) + automation_event_queue_.reset(new AutomationEventQueue); + + int observer_id = automation_event_queue_->AddObserver( + new DomRaisedEventObserver(automation_event_queue_.get(), event_name)); + scoped_ptr<DictionaryValue> return_value(new DictionaryValue); + return_value->SetInteger("observer_id", observer_id); + reply.SendSuccess(return_value.get()); +} + +void TestingAutomationProvider::RemoveEventObserver( + DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + int observer_id; + if (!args->GetInteger("observer_id", &observer_id) || + !automation_event_queue_.get()) { + reply.SendError("'observer_id' missing or invalid"); + return; + } + if (automation_event_queue_->RemoveObserver(observer_id)) { + reply.SendSuccess(NULL); + return; + } + reply.SendError("Invalid observer id."); +} + +void TestingAutomationProvider::ClearEventQueue( + DictionaryValue* args, + IPC::Message* reply_message) { + automation_event_queue_.reset(); + AutomationJSONReply(this, reply_message).SendSuccess(NULL); +} + +void TestingAutomationProvider::GetNextEvent( + DictionaryValue* args, + IPC::Message* reply_message) { + scoped_ptr<AutomationJSONReply> reply( + new AutomationJSONReply(this, reply_message)); + int observer_id; + bool blocking; + if (!args->GetInteger("observer_id", &observer_id)) { + reply->SendError("'observer_id' missing or invalid"); + return; + } + if (!args->GetBoolean("blocking", &blocking)) { + reply->SendError("'blocking' missing or invalid"); + return; + } + if (!automation_event_queue_.get()) { + reply->SendError( + "No observers are attached to the queue. Did you forget to add one?"); + return; + } + + // The reply will be freed once a matching event is added to the queue. + automation_event_queue_->GetNextEvent(reply.release(), observer_id, blocking); +} + void TestingAutomationProvider::GoForward( DictionaryValue* args, IPC::Message* reply_message) { diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index 50c4c5e..2df1da2 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -13,6 +13,8 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" +#include "chrome/browser/automation/automation_event_observer.h" +#include "chrome/browser/automation/automation_event_queue.h" #include "chrome/browser/automation/automation_provider.h" #include "chrome/browser/automation/automation_provider_json.h" #include "chrome/browser/history/history.h" @@ -944,6 +946,43 @@ class TestingAutomationProvider : public AutomationProvider, void ExecuteJavascriptJSON( base::DictionaryValue* args, IPC::Message* reply_message); + // Creates a DomRaisedEventObserver associated with the AutomationEventQueue. + // Example: + // input: { "event_name": "login complete", + // "windex": 1, + // "tab_index": 1, + // "frame_xpath": "//frames[1]", + // } + // output: { "observer_id": 1 } + void AddDomRaisedEventObserver( + base::DictionaryValue* args, IPC::Message* reply_message); + + // Removes an event observer associated with the AutomationEventQueue. + // Example: + // input: { "observer_id": 1 } + // output: none + void RemoveEventObserver( + base::DictionaryValue* args, IPC::Message* reply_message); + + // Retrieves an event from the AutomationEventQueue. + // Blocks if 'blocking' is true, otherwise returns immediately. + // Example: + // input: { "observer_id": 1, + // "blocking": true, + // } + // output: { "type": "raised", + // "name": "login complete" + // "id": 1, + // } + void GetNextEvent(base::DictionaryValue* args, IPC::Message* reply_message); + + // Removes all events and observers attached to the AutomationEventQueue. + // Example: + // input: none + // output: none + void ClearEventQueue( + base::DictionaryValue* args, IPC::Message* reply_message); + // Executes javascript in the specified frame of a render view. // Uses the JSON interface. Waits for a result from the // |DOMAutomationController|. The javascript must send a string. @@ -1563,6 +1602,10 @@ class TestingAutomationProvider : public AutomationProvider, // The stored data for the ImportSettings operation. ImportSettingsData import_settings_data_; + // The automation event observer queue. It is lazily created when an observer + // is added to avoid overhead when not needed. + scoped_ptr<AutomationEventQueue> automation_event_queue_; + DISALLOW_COPY_AND_ASSIGN(TestingAutomationProvider); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 0697c90..e6655c8 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -214,6 +214,10 @@ 'browser/auto_launch_trial.h', 'browser/automation/automation_browser_tracker.cc', 'browser/automation/automation_browser_tracker.h', + 'browser/automation/automation_event_observer.cc', + 'browser/automation/automation_event_observer.h', + 'browser/automation/automation_event_queue.cc', + 'browser/automation/automation_event_queue.h', 'browser/automation/automation_extension_tracker.cc', 'browser/automation/automation_extension_tracker.h', 'browser/automation/automation_provider.cc', diff --git a/chrome/test/data/apptest/basic.html b/chrome/test/data/apptest/basic.html new file mode 100644 index 0000000..2bce174 --- /dev/null +++ b/chrome/test/data/apptest/basic.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<!-- This is an example app used by chrome/functional/apptest.py to demonstrate + use of the Automation Event Queue for testing webapps. + + This example webapp uses explicitly raised events in a simulated + asyncronous login flow. --> +<html> + + <head> + <title>AppTest Example</title> + <script type="text/javascript"> + var globalTimeout; + + function write(str) { + document.getElementById("console").innerHTML += "> " + str + "<br \>"; + } + + /* Calls a function after a specified number of miliseconds. */ + function delayedCallback(f, ms) { + globalTimeout = setTimeout(f, ms); + } + + /* Adds an event with the given name to the AutomationEventQueue. */ + function raiseEvent(str) { + if (window.domAutomationController) { + window.domAutomationController.setAutomationId(424242) + window.domAutomationController.send(str); + } + } + + function init() { + write("Initializing..."); + delayedCallback(createLoginLink, 2000); + raiseEvent("init"); + } + + function createLoginLink() { + write("<a id='login' href='' onclick='return login();'>Log In</a>"); + raiseEvent("login ready"); + } + + function login() { + write("Logging in..."); + delayedCallback(loginSuccess, 2000); + raiseEvent("login start"); + return false; + } + + function loginSuccess() { + write("Login succeeded!"); + raiseEvent("login done"); + } + + function fail() { + clearTimeout(globalTimeout); + write("App failed!"); + raiseEvent("error"); + return false; + } + </script> + </head> + + <body onload="init()"> + <div id="s-1"> + [ <a id='fail' href='' onclick='return fail();'>Fail Test</a> ] + <br /><br /> + </div> + + <div id="console"> + </div> + + </body> + +</html> diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS index ece55df..df43a08 100644 --- a/chrome/test/functional/PYAUTO_TESTS +++ b/chrome/test/functional/PYAUTO_TESTS @@ -33,6 +33,7 @@ # This is the suite that gets run on 'Chromium' builds. 'CONTINUOUS': { 'all': [ + 'apptest', 'autofill', 'about_plugins_ui.AboutPluginsTest.testAboutPluginDetailInfo', 'bookmark_bar', diff --git a/chrome/test/functional/apptest.py b/chrome/test/functional/apptest.py new file mode 100644 index 0000000..fb351c0 --- /dev/null +++ b/chrome/test/functional/apptest.py @@ -0,0 +1,38 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import json + +import pyauto_functional # must be imported before pyauto +import pyauto + + +class PyAutoEventsTest(pyauto.PyUITest): + + def testBasicEvents(self): + """Basic test for the event queue.""" + url = self.GetHttpURLForDataPath('apptest', 'basic.html') + driver = self.NewWebDriver() + event_id = self.AddDomRaisedEventObserver(); + self.NavigateToURL(url) + self._ExpectEvent(event_id, 'init') + self._ExpectEvent(event_id, 'login ready') + driver.find_element_by_id('login').click() + self._ExpectEvent(event_id, 'login start') + self._ExpectEvent(event_id, 'login done') + + def _ExpectEvent(self, event_id, event_name): + # TODO(craigdh): Temporary hack to ignore unexpected events generated by + # chromedriver's use of DomAutomationController. The upcoming revision to + # RaisedEvents will fix this. Note this isn't polling, just ignoring + # chromedriver events. + while True: + event = json.loads(self.GetNextEvent(event_id).get('name')) + if event.find('{') == -1: + break + self.assertEqual(event, event_name) + + +if __name__ == '__main__': + pyauto_functional.Main() diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py index d605a6b..74861b4 100755 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -2806,6 +2806,92 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): return self._GetResultFromJSONRequest(cmd_dict, windex=windex, timeout=timeout) + def AddDomRaisedEventObserver(self, event_name=''): + """Adds a DomRaisedEventObserver associated with the AutomationEventQueue. + + Args: + event_name: The raised event name to watch for. By default all raised + events are observed. + + Returns: + The id of the created observer, which can be used with GetNextEvent(id) + and RemoveEventObserver(id). + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + # TODO(craigdh): Add documentation for raising an event once it has been + # implemented. + cmd_dict = { + 'command': 'AddDomRaisedEventObserver', + 'event_name': event_name, + } + return self._GetResultFromJSONRequest(cmd_dict, windex=None)['observer_id'] + + def GetNextEvent(self, observer_id=-1, blocking=True, timeout=-1): + """Waits for an observed event to occur. + + The returned event is removed from the Event Queue. If there is already a + matching event in the queue it is returned immediately, otherwise the call + blocks until a matching event occurs. If blocking is disabled and no + matching event is in the queue this function will immediately return None. + + Args: + observer_id: The id of the observer to wait for, matches any event by + default. + blocking: If True waits until there is a matching event in the queue, + if False and there is no event waiting in the queue returns None + immediately. + timeout: Time to wait for a matching event, defaults to the default + automation timeout. + + Returns: + Event response dictionary, or None if blocking is disabled and there is no + matching event in the queue. + SAMPLE: + { 'observer_id': 1, + 'name': 'login completed', + 'type': 'raised_event'} + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + cmd_dict = { + 'command': 'GetNextEvent', + 'observer_id' : observer_id, + 'blocking' : blocking, + } + return self._GetResultFromJSONRequest(cmd_dict, windex=None, + timeout=timeout) + + def RemoveEventObserver(self, observer_id): + """Removes an Event Observer from the AutomationEventQueue. + + Expects a valid observer_id. + + Args: + observer_id: The id of the observer to remove. + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + cmd_dict = { + 'command': 'RemoveEventObserver', + 'observer_id' : observer_id, + } + return self._GetResultFromJSONRequest(cmd_dict, windex=None) + + def ClearEventQueue(self): + """Removes all events currently in the AutomationEventQueue. + + Raises: + pyauto_errors.JSONInterfaceError if the automation call returns an error. + """ + cmd_dict = { + 'command': 'ClearEventQueue', + } + return self._GetResultFromJSONRequest(cmd_dict, windex=None) + def ExecuteJavascript(self, js, tab_index=0, windex=0, frame_xpath=''): """Executes a script in the specified frame of a tab. |