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() {} ...@@ -32,6 +32,23 @@ NavigationTracker::~NavigationTracker() {}
Status NavigationTracker::IsPendingNavigation(const std::string& frame_id, Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
bool* is_pending) { bool* is_pending) {
if (loading_state_ == kUnknown) { 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), // If the loading state is unknown (which happens after first connecting),
// force loading to start and set the state to loading. This will // 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 // 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, ...@@ -52,8 +69,7 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
"}"; "}";
base::DictionaryValue params; base::DictionaryValue params;
params.SetString("expression", kStartLoadingIfMainFrameNotLoading); params.SetString("expression", kStartLoadingIfMainFrameNotLoading);
scoped_ptr<base::DictionaryValue> result; status = client_->SendCommandAndGetResult(
Status status = client_->SendCommandAndGetResult(
"Runtime.evaluate", params, &result); "Runtime.evaluate", params, &result);
if (status.IsError()) if (status.IsError())
return Status(kUnknownError, "cannot determine loading status", status); return Status(kUnknownError, "cannot determine loading status", status);
...@@ -66,10 +82,13 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id, ...@@ -66,10 +82,13 @@ Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
loading_state_ = kLoading; loading_state_ = kLoading;
} }
*is_pending = loading_state_ == kLoading; *is_pending = loading_state_ == kLoading;
if (frame_id.empty()) if (frame_id.empty()) {
*is_pending |= scheduled_frame_set_.size() > 0; *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 |= scheduled_frame_set_.count(frame_id) > 0;
*is_pending |= pending_frame_set_.count(frame_id) > 0;
}
return Status(kOk); return Status(kOk);
} }
......
...@@ -257,15 +257,27 @@ namespace { ...@@ -257,15 +257,27 @@ namespace {
class FailToEvalScriptDevToolsClient : public StubDevToolsClient { class FailToEvalScriptDevToolsClient : public StubDevToolsClient {
public: public:
FailToEvalScriptDevToolsClient() : is_dom_getDocument_requested_(false) {}
virtual ~FailToEvalScriptDevToolsClient() {} virtual ~FailToEvalScriptDevToolsClient() {}
virtual Status SendCommandAndGetResult( virtual Status SendCommandAndGetResult(
const std::string& method, const std::string& method,
const base::DictionaryValue& params, const base::DictionaryValue& params,
scoped_ptr<base::DictionaryValue>* result) OVERRIDE { 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()); EXPECT_STREQ("Runtime.evaluate", method.c_str());
return Status(kUnknownError, "failed to eval script"); return Status(kUnknownError, "failed to eval script");
} }
private:
bool is_dom_getDocument_requested_;
}; };
} // namespace } // namespace
...@@ -284,10 +296,12 @@ namespace { ...@@ -284,10 +296,12 @@ namespace {
class DeterminingLoadStateDevToolsClient : public StubDevToolsClient { class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
public: public:
DeterminingLoadStateDevToolsClient( DeterminingLoadStateDevToolsClient(
bool has_empty_base_url,
bool is_loading, bool is_loading,
const std::string& send_event_first, const std::string& send_event_first,
base::DictionaryValue* send_event_first_params) 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_(send_event_first),
send_event_first_params_(send_event_first_params) {} send_event_first_params_(send_event_first_params) {}
...@@ -297,6 +311,16 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient { ...@@ -297,6 +311,16 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
const std::string& method, const std::string& method,
const base::DictionaryValue& params, const base::DictionaryValue& params,
scoped_ptr<base::DictionaryValue>* result) OVERRIDE { 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()) { if (send_event_first_.length()) {
Status status = listeners_.front() Status status = listeners_.front()
->OnEvent(this, send_event_first_, *send_event_first_params_); ->OnEvent(this, send_event_first_, *send_event_first_params_);
...@@ -311,6 +335,7 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient { ...@@ -311,6 +335,7 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
} }
private: private:
bool has_empty_base_url_;
bool is_loading_; bool is_loading_;
std::string send_event_first_; std::string send_event_first_;
base::DictionaryValue* send_event_first_params_; base::DictionaryValue* send_event_first_params_;
...@@ -318,9 +343,19 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient { ...@@ -318,9 +343,19 @@ class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
} // namespace } // 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) { TEST(NavigationTracker, UnknownStateForcesStart) {
base::DictionaryValue params; base::DictionaryValue params;
DeterminingLoadStateDevToolsClient client(true, std::string(), &params); DeterminingLoadStateDevToolsClient client(
false, true, std::string(), &params);
BrowserInfo browser_info; BrowserInfo browser_info;
NavigationTracker tracker(&client, &browser_info); NavigationTracker tracker(&client, &browser_info);
ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true)); ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
...@@ -330,7 +365,7 @@ TEST(NavigationTracker, UnknownStateForcesStartReceivesStop) { ...@@ -330,7 +365,7 @@ TEST(NavigationTracker, UnknownStateForcesStartReceivesStop) {
base::DictionaryValue params; base::DictionaryValue params;
params.SetString("frameId", "f"); params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client( DeterminingLoadStateDevToolsClient client(
true, "Page.frameStoppedLoading", &params); false, true, "Page.frameStoppedLoading", &params);
BrowserInfo browser_info; BrowserInfo browser_info;
NavigationTracker tracker(&client, &browser_info); NavigationTracker tracker(&client, &browser_info);
ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false)); ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
...@@ -340,7 +375,7 @@ TEST(NavigationTracker, OnSuccessfulNavigate) { ...@@ -340,7 +375,7 @@ TEST(NavigationTracker, OnSuccessfulNavigate) {
base::DictionaryValue params; base::DictionaryValue params;
params.SetString("frameId", "f"); params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client( DeterminingLoadStateDevToolsClient client(
true, "Page.frameStoppedLoading", &params); false, true, "Page.frameStoppedLoading", &params);
BrowserInfo browser_info; BrowserInfo browser_info;
NavigationTracker tracker( NavigationTracker tracker(
&client, NavigationTracker::kNotLoading, &browser_info); &client, NavigationTracker::kNotLoading, &browser_info);
...@@ -351,7 +386,8 @@ TEST(NavigationTracker, OnSuccessfulNavigate) { ...@@ -351,7 +386,8 @@ TEST(NavigationTracker, OnSuccessfulNavigate) {
TEST(NavigationTracker, OnSuccessfulNavigateStillWaiting) { TEST(NavigationTracker, OnSuccessfulNavigateStillWaiting) {
base::DictionaryValue params; base::DictionaryValue params;
params.SetString("frameId", "f"); params.SetString("frameId", "f");
DeterminingLoadStateDevToolsClient client(true, std::string(), &params); DeterminingLoadStateDevToolsClient client(
false, true, std::string(), &params);
BrowserInfo browser_info; BrowserInfo browser_info;
NavigationTracker tracker( NavigationTracker tracker(
&client, NavigationTracker::kNotLoading, &browser_info); &client, NavigationTracker::kNotLoading, &browser_info);
......
...@@ -53,8 +53,6 @@ _NEGATIVE_FILTER = [ ...@@ -53,8 +53,6 @@ _NEGATIVE_FILTER = [
_VERSION_SPECIFIC_FILTER = {} _VERSION_SPECIFIC_FILTER = {}
_VERSION_SPECIFIC_FILTER['HEAD'] = [ _VERSION_SPECIFIC_FILTER['HEAD'] = [
# https://code.google.com/p/chromedriver/issues/detail?id=815
'ChromeDriverTest.testShouldHandleNewWindowLoadingProperly',
] ]
_OS_SPECIFIC_FILTER = {} _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