| Index: chrome/test/chromedriver/window_commands.cc
|
| diff --git a/chrome/test/chromedriver/window_commands.cc b/chrome/test/chromedriver/window_commands.cc
|
| index 786f185b01ace9da3dc4ac7cd33df406425325fd..90611ae95a0a154a8fe39d86d8832cbf4448f051 100644
|
| --- a/chrome/test/chromedriver/window_commands.cc
|
| +++ b/chrome/test/chromedriver/window_commands.cc
|
| @@ -29,6 +29,7 @@
|
| #include "chrome/test/chromedriver/chrome/ui_events.h"
|
| #include "chrome/test/chromedriver/chrome/web_view.h"
|
| #include "chrome/test/chromedriver/element_util.h"
|
| +#include "chrome/test/chromedriver/net/timeout.h"
|
| #include "chrome/test/chromedriver/session.h"
|
| #include "chrome/test/chromedriver/util.h"
|
|
|
| @@ -203,6 +204,7 @@ Status ExecuteWindowCommand(
|
| Session* session,
|
| const base::DictionaryValue& params,
|
| scoped_ptr<base::Value>* value) {
|
| + Timeout timeout;
|
| WebView* web_view = NULL;
|
| Status status = session->GetTargetWindow(&web_view);
|
| if (status.IsError())
|
| @@ -233,19 +235,24 @@ Status ExecuteWindowCommand(
|
| }
|
|
|
| nav_status = web_view->WaitForPendingNavigations(
|
| - session->GetCurrentFrameId(), session->page_load_timeout, true);
|
| + session->GetCurrentFrameId(),
|
| + Timeout(session->page_load_timeout, &timeout),
|
| + true);
|
| if (nav_status.IsError())
|
| return nav_status;
|
|
|
| - status = command.Run(session, web_view, params, value);
|
| - if (status.code() == kNoSuchExecutionContext) {
|
| + status = command.Run(session, web_view, params, value, &timeout);
|
| + if (status.code() == kNoSuchExecutionContext ||
|
| + status.code() == kTimeout) {
|
| + // If the command timed out, let WaitForPendingNavigations cancel
|
| + // the navigation if there is one.
|
| continue;
|
| } else if (status.IsError()) {
|
| // If the command failed while a new page or frame started loading, retry
|
| // the command after the pending navigation has completed.
|
| bool is_pending = false;
|
| nav_status = web_view->IsPendingNavigation(session->GetCurrentFrameId(),
|
| - &is_pending);
|
| + &timeout, &is_pending);
|
| if (nav_status.IsError())
|
| return nav_status;
|
| else if (is_pending)
|
| @@ -255,7 +262,9 @@ Status ExecuteWindowCommand(
|
| }
|
|
|
| nav_status = web_view->WaitForPendingNavigations(
|
| - session->GetCurrentFrameId(), session->page_load_timeout, true);
|
| + session->GetCurrentFrameId(),
|
| + Timeout(session->page_load_timeout, &timeout),
|
| + true);
|
|
|
| if (status.IsOk() && nav_status.IsError() &&
|
| nav_status.code() != kUnexpectedAlertOpen)
|
| @@ -269,11 +278,13 @@ Status ExecuteGet(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| + timeout->SetDuration(session->page_load_timeout);
|
| std::string url;
|
| if (!params.GetString("url", &url))
|
| return Status(kUnknownError, "'url' must be a string");
|
| - Status status = web_view->Load(url);
|
| + Status status = web_view->Load(url, timeout);
|
| if (status.IsError())
|
| return status;
|
| session->SwitchToTopFrame();
|
| @@ -284,7 +295,8 @@ Status ExecuteExecuteScript(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string script;
|
| if (!params.GetString("script", &script))
|
| return Status(kUnknownError, "'script' must be a string");
|
| @@ -308,7 +320,8 @@ Status ExecuteExecuteAsyncScript(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string script;
|
| if (!params.GetString("script", &script))
|
| return Status(kUnknownError, "'script' must be a string");
|
| @@ -325,7 +338,8 @@ Status ExecuteSwitchToFrame(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const base::Value* id;
|
| if (!params.Get("id", &id))
|
| return Status(kUnknownError, "missing 'id'");
|
| @@ -396,7 +410,8 @@ Status ExecuteSwitchToParentFrame(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| session->SwitchToParentFrame();
|
| return Status(kOk);
|
| }
|
| @@ -405,7 +420,8 @@ Status ExecuteGetTitle(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const char kGetTitleScript[] = "function() { return document.title;}";
|
| base::ListValue args;
|
| return web_view->CallFunction(std::string(), kGetTitleScript, args, value);
|
| @@ -415,7 +431,8 @@ Status ExecuteGetPageSource(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const char kGetPageSource[] =
|
| "function() {"
|
| " return new XMLSerializer().serializeToString(document);"
|
| @@ -430,7 +447,8 @@ Status ExecuteFindElement(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return FindElement(interval_ms, true, NULL, session, web_view, params, value);
|
| }
|
|
|
| @@ -439,7 +457,8 @@ Status ExecuteFindElements(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return FindElement(
|
| interval_ms, false, NULL, session, web_view, params, value);
|
| }
|
| @@ -448,7 +467,8 @@ Status ExecuteGetCurrentUrl(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string url;
|
| Status status = GetUrl(web_view, std::string(), &url);
|
| if (status.IsError())
|
| @@ -483,7 +503,8 @@ Status ExecuteGoBack(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| Status status = web_view->TraverseHistory(-1);
|
| if (status.IsError())
|
| return status;
|
| @@ -495,7 +516,8 @@ Status ExecuteGoForward(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| Status status = web_view->TraverseHistory(1);
|
| if (status.IsError())
|
| return status;
|
| @@ -507,7 +529,8 @@ Status ExecuteRefresh(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| Status status = web_view->Reload();
|
| if (status.IsError())
|
| return status;
|
| @@ -519,7 +542,8 @@ Status ExecuteMouseMoveTo(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string element_id;
|
| bool has_element = params.GetString("element", &element_id);
|
| int x_offset = 0;
|
| @@ -557,7 +581,8 @@ Status ExecuteMouseClick(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| MouseButton button;
|
| Status status = GetMouseButton(params, &button);
|
| if (status.IsError())
|
| @@ -578,7 +603,8 @@ Status ExecuteMouseButtonDown(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| MouseButton button;
|
| Status status = GetMouseButton(params, &button);
|
| if (status.IsError())
|
| @@ -595,7 +621,8 @@ Status ExecuteMouseButtonUp(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| MouseButton button;
|
| Status status = GetMouseButton(params, &button);
|
| if (status.IsError())
|
| @@ -612,7 +639,8 @@ Status ExecuteMouseDoubleClick(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| MouseButton button;
|
| Status status = GetMouseButton(params, &button);
|
| if (status.IsError())
|
| @@ -633,7 +661,8 @@ Status ExecuteTouchDown(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return ExecuteTouchEvent(session, web_view, kTouchStart, params);
|
| }
|
|
|
| @@ -641,7 +670,8 @@ Status ExecuteTouchUp(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return ExecuteTouchEvent(session, web_view, kTouchEnd, params);
|
| }
|
|
|
| @@ -649,7 +679,8 @@ Status ExecuteTouchMove(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return ExecuteTouchEvent(session, web_view, kTouchMove, params);
|
| }
|
|
|
| @@ -657,7 +688,8 @@ Status ExecuteTouchScroll(
|
| Session *session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| if (session->chrome->GetBrowserInfo()->build_no < 2286) {
|
| // TODO(samuong): remove this once we stop supporting M41.
|
| return Status(kUnknownCommand, "Touch scroll action requires Chrome 42+");
|
| @@ -684,7 +716,8 @@ Status ExecuteTouchPinch(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| if (session->chrome->GetBrowserInfo()->build_no < 2286) {
|
| // TODO(samuong): remove this once we stop supporting M41.
|
| return Status(kUnknownCommand, "Pinch action requires Chrome 42+");
|
| @@ -704,7 +737,8 @@ Status ExecuteGetActiveElement(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return GetActiveElement(session, web_view, value);
|
| }
|
|
|
| @@ -712,7 +746,8 @@ Status ExecuteSendKeysToActiveElement(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const base::ListValue* key_list;
|
| if (!params.GetList("value", &key_list))
|
| return Status(kUnknownError, "'value' must be a list");
|
| @@ -724,7 +759,8 @@ Status ExecuteGetAppCacheStatus(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return web_view->EvaluateScript(
|
| session->GetCurrentFrameId(),
|
| "applicationCache.status",
|
| @@ -735,7 +771,8 @@ Status ExecuteIsBrowserOnline(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return web_view->EvaluateScript(
|
| session->GetCurrentFrameId(),
|
| "navigator.onLine",
|
| @@ -747,7 +784,8 @@ Status ExecuteGetStorageItem(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string key;
|
| if (!params.GetString("key", &key))
|
| return Status(kUnknownError, "'key' must be a string");
|
| @@ -765,7 +803,8 @@ Status ExecuteGetStorageKeys(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const char script[] =
|
| "var keys = [];"
|
| "for (var key in %s) {"
|
| @@ -783,7 +822,8 @@ Status ExecuteSetStorageItem(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string key;
|
| if (!params.GetString("key", &key))
|
| return Status(kUnknownError, "'key' must be a string");
|
| @@ -805,7 +845,8 @@ Status ExecuteRemoveStorageItem(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string key;
|
| if (!params.GetString("key", &key))
|
| return Status(kUnknownError, "'key' must be a string");
|
| @@ -823,7 +864,8 @@ Status ExecuteClearStorage(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return web_view->EvaluateScript(
|
| session->GetCurrentFrameId(),
|
| base::StringPrintf("%s.clear()", storage),
|
| @@ -835,7 +877,8 @@ Status ExecuteGetStorageSize(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return web_view->EvaluateScript(
|
| session->GetCurrentFrameId(),
|
| base::StringPrintf("%s.length", storage),
|
| @@ -846,7 +889,8 @@ Status ExecuteScreenshot(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| Status status = session->chrome->ActivateWebView(web_view->GetId());
|
| if (status.IsError())
|
| return status;
|
| @@ -878,7 +922,8 @@ Status ExecuteGetCookies(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::list<Cookie> cookies;
|
| Status status = GetVisibleCookies(web_view, &cookies);
|
| if (status.IsError())
|
| @@ -896,7 +941,8 @@ Status ExecuteAddCookie(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const base::DictionaryValue* cookie;
|
| if (!params.GetDictionary("cookie", &cookie))
|
| return Status(kUnknownError, "missing 'cookie'");
|
| @@ -911,7 +957,8 @@ Status ExecuteDeleteCookie(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string name;
|
| if (!params.GetString("name", &name))
|
| return Status(kUnknownError, "missing 'name'");
|
| @@ -928,7 +975,8 @@ Status ExecuteDeleteAllCookies(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::list<Cookie> cookies;
|
| Status status = GetVisibleCookies(web_view, &cookies);
|
| if (status.IsError())
|
| @@ -956,7 +1004,8 @@ Status ExecuteSetLocation(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| const base::DictionaryValue* location = NULL;
|
| Geoposition geoposition;
|
| if (!params.GetDictionary("location", &location) ||
|
| @@ -982,7 +1031,8 @@ Status ExecuteSetNetworkConditions(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| std::string network_name;
|
| const base::DictionaryValue* conditions = NULL;
|
| scoped_ptr<NetworkConditions> network_conditions(new NetworkConditions());
|
| @@ -1042,7 +1092,8 @@ Status ExecuteDeleteNetworkConditions(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| // Chrome does not have any command to stop overriding network conditions, so
|
| // we just override the network conditions with the "No throttling" preset.
|
| NetworkConditions network_conditions;
|
| @@ -1065,6 +1116,7 @@ Status ExecuteTakeHeapSnapshot(
|
| Session* session,
|
| WebView* web_view,
|
| const base::DictionaryValue& params,
|
| - scoped_ptr<base::Value>* value) {
|
| + scoped_ptr<base::Value>* value,
|
| + Timeout* timeout) {
|
| return web_view->TakeHeapSnapshot(value);
|
| }
|
|
|