Chromium Code Reviews| 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..fd7513652af1c80c2b8ebb2929cb261cdfaee04f 100644 |
| --- a/chrome/test/chromedriver/window_commands.cc |
| +++ b/chrome/test/chromedriver/window_commands.cc |
| @@ -203,6 +203,7 @@ Status ExecuteWindowCommand( |
| Session* session, |
| const base::DictionaryValue& params, |
| scoped_ptr<base::Value>* value) { |
| + Timeout timeout; |
|
samuong
2016/02/20 00:11:44
I might have misread how this works, but does time
|
| WebView* web_view = NULL; |
| Status status = session->GetTargetWindow(&web_view); |
| if (status.IsError()) |
| @@ -233,19 +234,24 @@ Status ExecuteWindowCommand( |
| } |
| nav_status = web_view->WaitForPendingNavigations( |
| - session->GetCurrentFrameId(), session->page_load_timeout, true); |
| + session->GetCurrentFrameId(), |
| + Timeout(session->page_load_timeout, &timeout), |
|
samuong
2016/02/20 00:11:44
...and if so, does that mean that the timeout dura
Alexander Semashko
2016/02/20 00:38:40
No, the outer timout's duration has effect only if
samuong
2016/02/22 23:55:35
Ah right, I misread the way TimeTicks::is_null() w
|
| + 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); |
|
samuong
2016/02/22 23:55:35
...however the call to command.Run here may or may
Alexander Semashko
2016/02/24 12:51:20
Good catch! I've changed the code so that it's ok
|
| + 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 +261,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 +277,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); |
|
samuong
2016/02/19 20:18:58
Is there a need to have a series of subtask timeou
Alexander Semashko
2016/02/19 23:38:59
Why not? Anyway, I could'n conceive a better (yet
samuong
2016/02/20 00:11:44
If the outer and inner timeouts have the same dura
Alexander Semashko
2016/02/20 00:38:40
Yeah, it is, only if they have the same duration.
samuong
2016/02/22 23:55:35
OK, it's fine if this is the same for now but you
|
| 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 +294,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 +319,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 +337,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 +409,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 +419,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 +430,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 +446,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 +456,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 +466,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 +502,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 +515,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 +528,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 +541,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 +580,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 +602,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 +620,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 +638,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 +660,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 +669,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 +678,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 +687,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 +715,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 +736,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 +745,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 +758,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 +770,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 +783,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 +802,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 +821,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 +844,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 +863,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 +876,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 +888,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 +921,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 +940,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 +956,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 +974,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 +1003,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 +1030,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 +1091,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 +1115,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); |
| } |