| Index: chrome/test/chromedriver/chrome/navigation_tracker.cc
|
| diff --git a/chrome/test/chromedriver/chrome/navigation_tracker.cc b/chrome/test/chromedriver/chrome/navigation_tracker.cc
|
| index ed1d1dfb4788536d7907490278cefd49165dcbed..13f527b7a8f1bd9841a3f6dd530894807df0b148 100644
|
| --- a/chrome/test/chromedriver/chrome/navigation_tracker.cc
|
| +++ b/chrome/test/chromedriver/chrome/navigation_tracker.cc
|
| @@ -126,7 +126,40 @@ Status NavigationTracker::OnEvent(DevToolsClient* client,
|
|
|
| Status NavigationTracker::OnCommandSuccess(DevToolsClient* client,
|
| const std::string& method) {
|
| - if (method == "Page.navigate")
|
| - loading_state_ = kLoading;
|
| + if (method == "Page.navigate" && loading_state_ != kLoading) {
|
| + // At this point the browser has initiated the navigation, but besides that,
|
| + // it is unknown what will happen.
|
| + //
|
| + // There are a few cases (perhaps more):
|
| + // 1 The RenderViewHost has already queued ViewMsg_Navigate and loading
|
| + // will start shortly.
|
| + // 2 The RenderViewHost has already queued ViewMsg_Navigate and loading
|
| + // will never start because it is just an in-page fragment navigation.
|
| + // 3 The RenderViewHost is suspended and hasn't queued ViewMsg_Navigate
|
| + // yet. This happens for cross-site navigations. The RenderViewHost
|
| + // will not queue ViewMsg_Navigate until it is ready to unload the
|
| + // previous page (after running unload handlers and such).
|
| + //
|
| + // To determine whether a load is expected, do a round trip to the
|
| + // renderer to ask what the URL is.
|
| + // If case #1, by the time the command returns, the frame started to load
|
| + // event will also have been received, since the DevTools command will
|
| + // be queued behind ViewMsg_Navigate.
|
| + // If case #2, by the time the command returns, the navigation will
|
| + // have already happened, although no frame start/stop events will have
|
| + // been received.
|
| + // If case #3, the URL will be blank if the navigation hasn't been started
|
| + // yet. In that case, expect a load to happen in the future.
|
| + base::DictionaryValue params;
|
| + params.SetString("expression", "document.URL");
|
| + scoped_ptr<base::DictionaryValue> result;
|
| + Status status = client_->SendCommandAndGetResult(
|
| + "Runtime.evaluate", params, &result);
|
| + std::string url;
|
| + if (status.IsError() || !result->GetString("result.value", &url))
|
| + return Status(kUnknownError, "cannot determine loading status", status);
|
| + if (url.empty())
|
| + loading_state_ = kLoading;
|
| + }
|
| return Status(kOk);
|
| }
|
|
|