Commit 59ed05ef authored by kkania@chromium.org's avatar kkania@chromium.org

[chromedriver] Remove unnecessary round trips to Chrome.

Change alerts system to not request page info from DevTools each command. Also don't fetch main frame ID each time, since NavigationTracker doesn't really need it.
BUG=none
R=chrisgao@chromium.org

Review URL: https://codereview.chromium.org/15393005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202610 0039d316-1c4b-4281-b951-d872f2087c98
parent 437a9f8f
......@@ -953,6 +953,8 @@
'sources': [
'../third_party/webdriver/atoms.cc',
'../third_party/webdriver/atoms.h',
'test/chromedriver/alert_commands.cc',
'test/chromedriver/alert_commands.h',
'test/chromedriver/basic_types.cc',
'test/chromedriver/basic_types.h',
'test/chromedriver/capabilities.cc',
......
// Copyright (c) 2013 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 "chrome/test/chromedriver/alert_commands.h"
#include "base/values.h"
#include "chrome/test/chromedriver/chrome/chrome.h"
#include "chrome/test/chromedriver/chrome/devtools_client.h"
#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/web_view.h"
#include "chrome/test/chromedriver/session.h"
Status ExecuteAlertCommand(
const AlertCommand& alert_command,
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
WebView* web_view = NULL;
Status status = session->GetTargetWindow(&web_view);
if (status.IsError())
return status;
status = web_view->ConnectIfNecessary();
if (status.IsError())
return status;
status = web_view->GetDevToolsClient()->HandleReceivedEvents();
if (status.IsError())
return status;
status = web_view->WaitForPendingNavigations(session->GetCurrentFrameId());
if (status.IsError() && status.code() != kUnexpectedAlertOpen)
return status;
return alert_command.Run(session, web_view, params, value);
}
Status ExecuteGetAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
value->reset(base::Value::CreateBooleanValue(
web_view->GetJavaScriptDialogManager()->IsDialogOpen()));
return Status(kOk);
}
Status ExecuteGetAlertText(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
std::string message;
Status status =
web_view->GetJavaScriptDialogManager()->GetDialogMessage(&message);
if (status.IsError())
return status;
value->reset(base::Value::CreateStringValue(message));
return Status(kOk);
}
Status ExecuteSetAlertValue(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
std::string text;
if (!params.GetString("text", &text))
return Status(kUnknownError, "missing or invalid 'text'");
if (!web_view->GetJavaScriptDialogManager()->IsDialogOpen())
return Status(kNoAlertOpen);
session->prompt_text.reset(new std::string(text));
return Status(kOk);
}
Status ExecuteAcceptAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
Status status = web_view->GetJavaScriptDialogManager()
->HandleDialog(true, session->prompt_text.get());
session->prompt_text.reset();
return status;
}
Status ExecuteDismissAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
Status status = web_view->GetJavaScriptDialogManager()
->HandleDialog(false, session->prompt_text.get());
session->prompt_text.reset();
return status;
}
// Copyright (c) 2013 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_TEST_CHROMEDRIVER_ALERT_COMMANDS_H_
#define CHROME_TEST_CHROMEDRIVER_ALERT_COMMANDS_H_
#include "base/callback_forward.h"
#include "base/memory/scoped_ptr.h"
namespace base {
class DictionaryValue;
class Value;
}
struct Session;
class Status;
class WebView;
typedef base::Callback<Status(
Session* session,
WebView* web_view,
const base::DictionaryValue&,
scoped_ptr<base::Value>*)> AlertCommand;
// Executes an alert command.
Status ExecuteAlertCommand(
const AlertCommand& alert_command,
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Returns whether an alert is open.
Status ExecuteGetAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Returns the text of the open alert.
Status ExecuteGetAlertText(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Sets the value of the alert prompt.
Status ExecuteSetAlertValue(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Accepts the open alert.
Status ExecuteAcceptAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Dismisses the open alert.
Status ExecuteDismissAlert(
Session* session,
WebView* web_view,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
#endif // CHROME_TEST_CHROMEDRIVER_ALERT_COMMANDS_H_
......@@ -29,17 +29,6 @@ class Chrome {
// Closes the specified WebView.
virtual Status CloseWebView(const std::string& id) = 0;
// Returns whether a JavaScript dialog is open.
virtual Status IsJavaScriptDialogOpen(bool* is_open) = 0;
// Returns the message of the open JavaScript dialog.
virtual Status GetJavaScriptDialogMessage(std::string* message) = 0;
// Handles an open JavaScript dialog. |prompt_text| may be NULL to signify
// not to set the prompt text.
virtual Status HandleJavaScriptDialog(bool accept,
const std::string* prompt_text) = 0;
// Gets the automation extension.
virtual Status GetAutomationExtension(AutomationExtension** extension) = 0;
......
......@@ -5,15 +5,13 @@
#include "chrome/test/chromedriver/chrome/chrome_impl.h"
#include "chrome/test/chromedriver/chrome/devtools_client.h"
#include "chrome/test/chromedriver/chrome/devtools_event_listener.h"
#include "chrome/test/chromedriver/chrome/devtools_http_client.h"
#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h"
#include "chrome/test/chromedriver/chrome/log.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/web_view_impl.h"
ChromeImpl::~ChromeImpl() {
web_views_.clear();
}
ChromeImpl::~ChromeImpl() {}
std::string ChromeImpl::GetVersion() {
return version_;
......@@ -101,38 +99,6 @@ Status ChromeImpl::CloseWebView(const std::string& id) {
return Status(kOk);
}
Status ChromeImpl::IsJavaScriptDialogOpen(bool* is_open) {
JavaScriptDialogManager* manager;
Status status = GetDialogManagerForOpenDialog(&manager);
if (status.IsError())
return status;
*is_open = manager != NULL;
return Status(kOk);
}
Status ChromeImpl::GetJavaScriptDialogMessage(std::string* message) {
JavaScriptDialogManager* manager;
Status status = GetDialogManagerForOpenDialog(&manager);
if (status.IsError())
return status;
if (!manager)
return Status(kNoAlertOpen);
return manager->GetDialogMessage(message);
}
Status ChromeImpl::HandleJavaScriptDialog(bool accept,
const std::string* prompt_text) {
JavaScriptDialogManager* manager;
Status status = GetDialogManagerForOpenDialog(&manager);
if (status.IsError())
return status;
if (!manager)
return Status(kNoAlertOpen);
return manager->HandleDialog(accept, prompt_text);
}
Status ChromeImpl::GetAutomationExtension(AutomationExtension** extension) {
return Status(kUnknownError, "automation extension not supported");
}
......@@ -149,25 +115,3 @@ ChromeImpl::ChromeImpl(
build_no_(build_no) {
devtools_event_listeners_.swap(devtools_event_listeners);
}
Status ChromeImpl::GetDialogManagerForOpenDialog(
JavaScriptDialogManager** manager) {
std::list<std::string> web_view_ids;
Status status = GetWebViewIds(&web_view_ids);
if (status.IsError())
return status;
for (std::list<std::string>::const_iterator it = web_view_ids.begin();
it != web_view_ids.end(); ++it) {
WebView* web_view;
status = GetWebViewById(*it, &web_view);
if (status.IsError())
return status;
if (web_view->GetJavaScriptDialogManager()->IsDialogOpen()) {
*manager = web_view->GetJavaScriptDialogManager();
return Status(kOk);
}
}
*manager = NULL;
return Status(kOk);
}
......@@ -34,11 +34,6 @@ class ChromeImpl : public Chrome {
virtual Status GetWebViewById(const std::string& id,
WebView** web_view) OVERRIDE;
virtual Status CloseWebView(const std::string& id) OVERRIDE;
virtual Status IsJavaScriptDialogOpen(bool* is_open) OVERRIDE;
virtual Status GetJavaScriptDialogMessage(std::string* message) OVERRIDE;
virtual Status HandleJavaScriptDialog(
bool accept,
const std::string* prompt_text) OVERRIDE;
virtual Status GetAutomationExtension(
AutomationExtension** extension) OVERRIDE;
......@@ -56,8 +51,6 @@ class ChromeImpl : public Chrome {
private:
typedef std::list<linked_ptr<WebViewImpl> > WebViewList;
Status GetDialogManagerForOpenDialog(JavaScriptDialogManager** manager);
std::string version_;
int build_no_;
......
......@@ -14,11 +14,9 @@ JavaScriptDialogManager::JavaScriptDialogManager(DevToolsClient* client)
client_->AddListener(this);
}
JavaScriptDialogManager::~JavaScriptDialogManager() {
}
JavaScriptDialogManager::~JavaScriptDialogManager() {}
bool JavaScriptDialogManager::IsDialogOpen() {
client_->HandleReceivedEvents();
return !unhandled_dialog_queue_.empty();
}
......
......@@ -61,8 +61,11 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
if (loading_state_ == kUnknown)
loading_state_ = kLoading;
}
*is_pending = (loading_state_ == kLoading) ||
scheduled_frame_set_.count(frame_id) > 0;
*is_pending = loading_state_ == kLoading;
if (frame_id.empty())
*is_pending |= scheduled_frame_set_.size() > 0;
else
*is_pending |= scheduled_frame_set_.count(frame_id) > 0;
return Status(kOk);
}
......@@ -118,5 +121,8 @@ void NavigationTracker::OnEvent(DevToolsClient* client,
const base::Value* unused_value;
if (!params.Get("frame.parentId", &unused_value))
scheduled_frame_set_.clear();
} else if (method == "Inspector.targetCrashed") {
loading_state_ = kNotLoading;
scheduled_frame_set_.clear();
}
}
......@@ -33,6 +33,8 @@ class NavigationTracker : public DevToolsEventListener {
NavigationTracker(DevToolsClient* client, LoadingState known_state);
virtual ~NavigationTracker();
// Gets whether a navigation is pending for the specified frame. |frame_id|
// may be empty to signify the main frame.
Status IsPendingNavigation(const std::string& frame_id, bool* is_pending);
// Overridden from DevToolsEventListener:
......
......@@ -30,20 +30,6 @@ Status StubChrome::CloseWebView(const std::string& id) {
return Status(kOk);
}
Status StubChrome::IsJavaScriptDialogOpen(bool* is_open) {
return Status(kOk);
}
Status StubChrome::GetJavaScriptDialogMessage(std::string* message) {
return Status(kOk);
}
Status StubChrome::HandleJavaScriptDialog(
bool accept,
const std::string* prompt_text) {
return Status(kOk);
}
Status StubChrome::GetAutomationExtension(AutomationExtension** extension) {
return Status(kOk);
}
......
......@@ -25,11 +25,6 @@ class StubChrome : public Chrome {
virtual Status GetWebViewById(const std::string& id,
WebView** web_view) OVERRIDE;
virtual Status CloseWebView(const std::string& id) OVERRIDE;
virtual Status IsJavaScriptDialogOpen(bool* is_open) OVERRIDE;
virtual Status GetJavaScriptDialogMessage(std::string* message) OVERRIDE;
virtual Status HandleJavaScriptDialog(
bool accept,
const std::string* prompt_text) OVERRIDE;
virtual Status GetAutomationExtension(
AutomationExtension** extension) OVERRIDE;
virtual std::string GetOperatingSystemName() OVERRIDE;
......
......@@ -20,6 +20,10 @@ Status StubWebView::ConnectIfNecessary() {
return Status(kOk);
}
DevToolsClient* StubWebView::GetDevToolsClient() {
return NULL;
}
Status StubWebView::Load(const std::string& url) {
return Status(kOk);
}
......@@ -90,10 +94,6 @@ Status StubWebView::IsPendingNavigation(const std::string& frame_id,
return Status(kOk);
}
Status StubWebView::GetMainFrame(std::string* frame_id) {
return Status(kOk);
}
JavaScriptDialogManager* StubWebView::GetJavaScriptDialogManager() {
return NULL;
}
......
......@@ -20,6 +20,7 @@ class StubWebView : public WebView {
// Overridden from WebView:
virtual std::string GetId() OVERRIDE;
virtual Status ConnectIfNecessary() OVERRIDE;
virtual DevToolsClient* GetDevToolsClient() OVERRIDE;
virtual Status Load(const std::string& url) OVERRIDE;
virtual Status Reload() OVERRIDE;
virtual Status EvaluateScript(const std::string& frame,
......@@ -54,7 +55,6 @@ class StubWebView : public WebView {
const std::string& frame_id) OVERRIDE;
virtual Status IsPendingNavigation(
const std::string& frame_id, bool* is_pending) OVERRIDE;
virtual Status GetMainFrame(std::string* frame_id) OVERRIDE;
virtual JavaScriptDialogManager* GetJavaScriptDialogManager() OVERRIDE;
virtual Status OverrideGeolocation(const Geoposition& geoposition) OVERRIDE;
virtual Status CaptureScreenshot(std::string* screenshot) OVERRIDE;
......
......@@ -19,6 +19,7 @@ class TimeDelta;
class Value;
}
class DevToolsClient;
struct Geoposition;
class JavaScriptDialogManager;
struct KeyEvent;
......@@ -35,6 +36,9 @@ class WebView {
// Make DevToolsCient connect to DevTools if it is disconnected.
virtual Status ConnectIfNecessary() = 0;
// Return the DevToolsClient.
virtual DevToolsClient* GetDevToolsClient() = 0;
// Load a given URL in the main frame.
virtual Status Load(const std::string& url) = 0;
......@@ -109,9 +113,6 @@ class WebView {
virtual Status IsPendingNavigation(
const std::string& frame_id, bool* is_pending) = 0;
// Returns the frame id for the main frame.
virtual Status GetMainFrame(std::string* out_frame) = 0;
// Returns the JavaScriptDialogManager. Never null.
virtual JavaScriptDialogManager* GetJavaScriptDialogManager() = 0;
......
......@@ -106,6 +106,10 @@ Status WebViewImpl::ConnectIfNecessary() {
return client_->ConnectIfNecessary();
}
DevToolsClient* WebViewImpl::GetDevToolsClient() {
return client_.get();
}
Status WebViewImpl::Load(const std::string& url) {
base::DictionaryValue params;
params.SetString("url", url);
......@@ -250,43 +254,19 @@ Status WebViewImpl::DeleteCookie(const std::string& name,
}
Status WebViewImpl::WaitForPendingNavigations(const std::string& frame_id) {
std::string full_frame_id(frame_id);
if (full_frame_id.empty()) {
Status status = GetMainFrame(&full_frame_id);
if (status.IsError())
return status;
}
log_->AddEntry(Log::kLog, "waiting for pending navigations");
Status status = client_->HandleEventsUntil(
base::Bind(&WebViewImpl::IsNotPendingNavigation, base::Unretained(this),
full_frame_id));
frame_id));
log_->AddEntry(Log::kLog, "done waiting for pending navigations");
return status;
}
Status WebViewImpl::IsPendingNavigation(const std::string& frame_id,
bool* is_pending) {
std::string full_frame_id(frame_id);
if (full_frame_id.empty()) {
Status status = GetMainFrame(&full_frame_id);
if (status.IsError())
return status;
}
return navigation_tracker_->IsPendingNavigation(frame_id, is_pending);
}
Status WebViewImpl::GetMainFrame(std::string* out_frame) {
base::DictionaryValue params;
scoped_ptr<base::DictionaryValue> result;
Status status = client_->SendCommandAndGetResult(
"Page.getResourceTree", params, &result);
if (status.IsError())
return status;
if (!result->GetString("frameTree.frame.id", out_frame))
return Status(kUnknownError, "missing 'frameTree.frame.id' in response");
return Status(kOk);
}
JavaScriptDialogManager* WebViewImpl::GetJavaScriptDialogManager() {
return dialog_manager_.get();
}
......
......@@ -39,6 +39,7 @@ class WebViewImpl : public WebView {
// Overridden from WebView:
virtual std::string GetId() OVERRIDE;
virtual Status ConnectIfNecessary() OVERRIDE;
virtual DevToolsClient* GetDevToolsClient() OVERRIDE;
virtual Status Load(const std::string& url) OVERRIDE;
virtual Status Reload() OVERRIDE;
virtual Status EvaluateScript(const std::string& frame,
......@@ -73,7 +74,6 @@ class WebViewImpl : public WebView {
const std::string& frame_id) OVERRIDE;
virtual Status IsPendingNavigation(
const std::string& frame_id, bool* is_pending) OVERRIDE;
virtual Status GetMainFrame(std::string* out_frame) OVERRIDE;
virtual JavaScriptDialogManager* GetJavaScriptDialogManager() OVERRIDE;
virtual Status OverrideGeolocation(const Geoposition& geoposition) OVERRIDE;
virtual Status CaptureScreenshot(std::string* screenshot) OVERRIDE;
......
......@@ -11,6 +11,7 @@
#include "base/stringprintf.h"
#include "base/sys_info.h"
#include "base/values.h"
#include "chrome/test/chromedriver/alert_commands.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/version.h"
#include "chrome/test/chromedriver/command_names.h"
......
......@@ -289,90 +289,6 @@ Status ExecuteImplicitlyWait(
return Status(kOk);
}
Status ExecuteAlertCommand(
const SessionCommand& alert_command,
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
WebView* web_view = NULL;
Status status = session->GetTargetWindow(&web_view);
if (status.IsError())
return status;
status = web_view->ConnectIfNecessary();
if (status.IsError())
return status;
status = web_view->WaitForPendingNavigations(session->GetCurrentFrameId());
if (status.IsError() && status.code() != kUnexpectedAlertOpen)
return status;
return alert_command.Run(session, params, value);
}
Status ExecuteGetAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
bool is_open;
Status status = session->chrome->IsJavaScriptDialogOpen(&is_open);
if (status.IsError())
return status;
value->reset(base::Value::CreateBooleanValue(is_open));
return Status(kOk);
}
Status ExecuteGetAlertText(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
std::string message;
Status status = session->chrome->GetJavaScriptDialogMessage(&message);
if (status.IsError())
return status;
value->reset(base::Value::CreateStringValue(message));
return Status(kOk);
}
Status ExecuteSetAlertValue(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
std::string text;
if (!params.GetString("text", &text))
return Status(kUnknownError, "missing or invalid 'text'");
bool is_open;
Status status = session->chrome->IsJavaScriptDialogOpen(&is_open);
if (status.IsError())
return status;
if (!is_open)
return Status(kNoAlertOpen);
session->prompt_text.reset(new std::string(text));
return Status(kOk);
}
Status ExecuteAcceptAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
Status status = session->chrome->HandleJavaScriptDialog(
true, session->prompt_text.get());
session->prompt_text.reset();
return status;
}
Status ExecuteDismissAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
Status status = session->chrome->HandleJavaScriptDialog(
false, session->prompt_text.get());
session->prompt_text.reset();
return status;
}
Status ExecuteIsLoading(
Session* session,
const base::DictionaryValue& params,
......
......@@ -18,7 +18,6 @@ class Value;
struct Session;
class Status;
class WebView;
typedef base::Callback<Status(
Session* session,
......@@ -95,43 +94,6 @@ Status ExecuteImplicitlyWait(
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Executes an alert command.
Status ExecuteAlertCommand(
const SessionCommand& alert_command,
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Returns whether an alert is open.
Status ExecuteGetAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Returns the text of the open alert.
Status ExecuteGetAlertText(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Sets the value of the alert prompt.
Status ExecuteSetAlertValue(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Accepts the open alert.
Status ExecuteAcceptAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
// Dismisses the open alert.
Status ExecuteDismissAlert(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value);
Status ExecuteIsLoading(
Session* session,
const base::DictionaryValue& params,
......
......@@ -14,7 +14,9 @@
#include "base/values.h"
#include "chrome/test/chromedriver/basic_types.h"
#include "chrome/test/chromedriver/chrome/chrome.h"
#include "chrome/test/chromedriver/chrome/devtools_client.h"
#include "chrome/test/chromedriver/chrome/geoposition.h"
#include "chrome/test/chromedriver/chrome/javascript_dialog_manager.h"
#include "chrome/test/chromedriver/chrome/js.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/ui_events.h"
......@@ -126,22 +128,22 @@ Status ExecuteWindowCommand(
Session* session,
const base::DictionaryValue& params,
scoped_ptr<base::Value>* value) {
bool is_dialog_open;
Status status = session->chrome->IsJavaScriptDialogOpen(&is_dialog_open);
WebView* web_view = NULL;
Status status = session->GetTargetWindow(&web_view);
if (status.IsError())
return status;
if (is_dialog_open)
return Status(kUnexpectedAlertOpen);
WebView* web_view = NULL;
status = session->GetTargetWindow(&web_view);
status = web_view->ConnectIfNecessary();
if (status.IsError())
return status;
status = web_view->ConnectIfNecessary();
status = web_view->GetDevToolsClient()->HandleReceivedEvents();
if (status.IsError())
return status;
if (web_view->GetJavaScriptDialogManager()->IsDialogOpen())
return Status(kUnexpectedAlertOpen);
Status nav_status =
web_view->WaitForPendingNavigations(session->GetCurrentFrameId());
if (nav_status.IsError())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment