Commit af416844 authored by stgao's avatar stgao Committed by Commit bot

[ChromeDriver] Detect page loading status when the page is not loaded at all.

BUG=chromedriver:815

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

Cr-Commit-Position: refs/heads/master@{#297468}
parent b6273442
......@@ -32,6 +32,23 @@ NavigationTracker::~NavigationTracker() {}
Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
bool* is_pending) {
if (loading_state_ == kUnknown) {
scoped_ptr<base::DictionaryValue> result;
// In the case that a http request is sent to server to fetch the page
// content and the server hasn't responded at all, a dummy page is created
// for the new window. In such case, the baseURL will be empty.
base::DictionaryValue empty_params;
Status status = client_->SendCommandAndGetResult(
"DOM.getDocument", empty_params, &result);
std::string base_url;
if (status.IsError() || !result->GetString("root.baseURL", &base_url))
return Status(kUnknownError, "cannot determine loading status", status);
if (base_url.empty()) {
*is_pending = true;
loading_state_ = kLoading;
return Status(kOk);
}
// If the loading state is unknown (which happens after first connecting),
// force loading to start and set the state to loading. This will
// cause a frame start event to be received, and the frame stop event
......@@ -52,8 +69,7 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
"}";
base::DictionaryValue params;
params.SetString("expression", kStartLoadingIfMainFrameNotLoading);
scoped_ptr<base::DictionaryValue> result;
Status status = client_->SendCommandAndGetResult(
status = client_->SendCommandAndGetResult(
"Runtime.evaluate", params, &result);
if (status.IsError())
return Status(kUnknownError, "cannot determine loading status", status);
......@@ -66,10 +82,13 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
loading_state_ = kLoading;
}
*is_pending = loading_state_ == kLoading;
if (frame_id.empty())
if (frame_id.empty()) {
*is_pending |= scheduled_frame_set_.size() > 0;
else
*is_pending |= pending_frame_set_.size() > 0;
} else {
*is_pending |= scheduled_frame_set_.count(frame_id) > 0;
*is_pending |= pending_frame_set_.count(frame_id) > 0;
}
return Status(kOk);
}
......
......@@ -257,15 +257,27 @@ namespace {
class FailToEvalScriptDevToolsClient : public StubDevToolsClient {
public:
FailToEvalScriptDevToolsClient() : is_dom_getDocument_requested_(false) {}
virtual ~FailToEvalScriptDevToolsClient() {}
virtual Status SendCommandAndGetResult(
const std::string& method,
const base::DictionaryValue& params,
scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
if (!is_dom_getDocument_requested_ && method == "DOM.getDocument") {
is_dom_getDocument_requested_ = true;
base::DictionaryValue result_dict;
result_dict.SetString("root.baseURL", "http://test");
result->reset(result_dict.DeepCopy());
return Status(kOk);
}
EXPECT_STREQ("Runtime.evaluate", method.c_str());
return Status(kUnknownError, "failed to eval script");
}
private:
bool is_dom_getDocument_requested_;
};
} // namespace
......@@ -284,10 +296,12 @@ namespace {
class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
public:
DeterminingLoadStateDevToolsClient(
bool has_empty_base_url,
bool is_loading,
const std::string& send_event_first,
base::DictionaryValue* send_event_first_params)
: is_loading_(is_loading),
: has_empty_base_url_(has_empty_base_url),
is_loading_(is_loading),
send_event_first_(send_event_first),
send_event_first_params_(send_event_first_params) {}
......@@ -297,6 +311,16 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
const std::string& method,
const base::DictionaryValue& params,
scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
if (method == "DOM.getDocument") {
base::DictionaryValue result_dict;
if (has_empty_base_url_)
result_dict.SetString("root.baseURL", std::string());
else
result_dict.SetString("root.baseURL", "http://test");
result->reset(result_dict.DeepCopy());
return Status(kOk);
}
if (send_event_first_.length()) {
Status status = listeners_.front()
->OnEvent(this, send_event_first_, *send_event_first_params_);
......@@ -311,6 +335,7 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
}
private:
bool has_empty_base_url_;
bool is_loading_;
std::string send_event_first_;
base::DictionaryValue* send_event_first_params_;
......@@ -318,9 +343,19 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
} // namespace
TEST(NavigationTracker, UnknownStatePageNotLoadAtAll) {
base::DictionaryValue params;
DeterminingLoadStateDevToolsClient client(
true, true, std::string(), &params);
BrowserInfo browser_info;
NavigationTracker tracker(&client, &browser_info);
ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
}
TEST(NavigationTracker, UnknownStateForcesStart) {
base::DictionaryValue params;
DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
DeterminingLoadStateDevToolsClient client(
false, true, std::string(), &params);
BrowserInfo browser_info;
NavigationTracker tracker(&client, &browser_info);
ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
......@@ -330,7 +365,7 @@ TEST(NavigationTracker, UnknownStateForcesStartReceivesStop) {
base::DictionaryValue params;
params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client(
true, "Page.frameStoppedLoading", &params);
false, true, "Page.frameStoppedLoading", &params);
BrowserInfo browser_info;
NavigationTracker tracker(&client, &browser_info);
ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
......@@ -340,7 +375,7 @@ TEST(NavigationTracker, OnSuccessfulNavigate) {
base::DictionaryValue params;
params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client(
true, "Page.frameStoppedLoading", &params);
false, true, "Page.frameStoppedLoading", &params);
BrowserInfo browser_info;
NavigationTracker tracker(
&client, NavigationTracker::kNotLoading, &browser_info);
......@@ -351,7 +386,8 @@ TEST(NavigationTracker, OnSuccessfulNavigate) {
TEST(NavigationTracker, OnSuccessfulNavigateStillWaiting) {
base::DictionaryValue params;
params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
DeterminingLoadStateDevToolsClient client(
false, true, std::string(), &params);
BrowserInfo browser_info;
NavigationTracker tracker(
&client, NavigationTracker::kNotLoading, &browser_info);
......
......@@ -53,8 +53,6 @@ _NEGATIVE_FILTER = [
_VERSION_SPECIFIC_FILTER = {}
_VERSION_SPECIFIC_FILTER['HEAD'] = [
# https://code.google.com/p/chromedriver/issues/detail?id=815
'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
]
_OS_SPECIFIC_FILTER = {}
......
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