Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: chrome/test/chromedriver/navigation_tracker.cc

Issue 12848005: [chromedriver] Separate stuff of chrome from chromedriver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments and fix compile error on mac. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/test/chromedriver/navigation_tracker.h"
6
7 #include "base/logging.h"
8 #include "base/stringprintf.h"
9 #include "base/values.h"
10 #include "chrome/test/chromedriver/devtools_client.h"
11 #include "chrome/test/chromedriver/status.h"
12
13 NavigationTracker::NavigationTracker(DevToolsClient* client)
14 : client_(client),
15 loading_state_(kUnknown) {
16 client_->AddListener(this);
17 }
18
19 NavigationTracker::NavigationTracker(DevToolsClient* client,
20 LoadingState known_state)
21 : client_(client),
22 loading_state_(known_state) {
23 client_->AddListener(this);
24 }
25
26 NavigationTracker::~NavigationTracker() {}
27
28 Status NavigationTracker::IsPendingNavigation(const std::string& frame_id,
29 bool* is_pending) {
30 if (loading_state_ == kUnknown) {
31 // If the loading state is unknown (which happens after first connecting),
32 // force loading to start and set the state to loading. This will
33 // cause a frame start event to be received, and the frame stop event
34 // will not be received until all frames are loaded.
35 // Loading is forced to start by attaching a temporary iframe.
36 // Forcing loading to start is not necessary if the main frame is not yet
37 // loaded.
38 const char kStartLoadingIfMainFrameNotLoading[] =
39 "var isLoaded = document.readyState == 'complete' ||"
40 " document.readyState == 'interactive';"
41 "if (isLoaded) {"
42 " var frame = document.createElement('iframe');"
43 " frame.src = 'about:blank';"
44 " document.body.appendChild(frame);"
45 " window.setTimeout(function() {"
46 " document.body.removeChild(frame);"
47 " }, 0);"
48 "}";
49 base::DictionaryValue params;
50 params.SetString("expression", kStartLoadingIfMainFrameNotLoading);
51 scoped_ptr<base::DictionaryValue> result;
52 Status status = client_->SendCommandAndGetResult(
53 "Runtime.evaluate", params, &result);
54 if (status.IsError())
55 return Status(kUnknownError, "cannot determine loading status", status);
56
57 // Between the time the JavaScript is evaluated and SendCommandAndGetResult
58 // returns, OnEvent may have received info about the loading state.
59 // This is only possible during a nested command. Only set the loading state
60 // if the loading state is still unknown.
61 if (loading_state_ == kUnknown)
62 loading_state_ = kLoading;
63 }
64 *is_pending = (loading_state_ == kLoading) ||
65 scheduled_frame_set_.count(frame_id) > 0;
66 return Status(kOk);
67 }
68
69 Status NavigationTracker::OnConnected() {
70 loading_state_ = kUnknown;
71 scheduled_frame_set_.clear();
72
73 // Enable page domain notifications to allow tracking navigation state.
74 base::DictionaryValue empty_params;
75 return client_->SendCommand("Page.enable", empty_params);
76 }
77
78 void NavigationTracker::OnEvent(const std::string& method,
79 const base::DictionaryValue& params) {
80 // Chrome does not send Page.frameStoppedLoading until all frames have
81 // run their onLoad handlers (including frames created during the handlers).
82 // When it does, it only sends one stopped event for all frames.
83 if (method == "Page.frameStartedLoading") {
84 loading_state_ = kLoading;
85 } else if (method == "Page.frameStoppedLoading") {
86 loading_state_ = kNotLoading;
87 } else if (method == "Page.frameScheduledNavigation") {
88 double delay;
89 if (!params.GetDouble("delay", &delay)) {
90 LOG(ERROR) << "missing or invalid 'delay'";
91 return;
92 }
93 std::string frame_id;
94 if (!params.GetString("frameId", &frame_id)) {
95 LOG(ERROR) << "missing or invalid 'frameId'";
96 return;
97 }
98 // WebDriver spec says to ignore redirects over 1s.
99 if (delay > 1)
100 return;
101 scheduled_frame_set_.insert(frame_id);
102 } else if (method == "Page.frameClearedScheduledNavigation") {
103 std::string frame_id;
104 if (!params.GetString("frameId", &frame_id)) {
105 LOG(ERROR) << "missing or invalid 'frameId'";
106 return;
107 }
108 scheduled_frame_set_.erase(frame_id);
109 } else if (method == "Page.frameNavigated") {
110 // Note: in some cases Page.frameNavigated may be received for subframes
111 // without a frameStoppedLoading (for example cnn.com).
112
113 // If the main frame just navigated, discard any pending scheduled
114 // navigations. For some reasons at times the cleared event is not
115 // received when navigating.
116 // See crbug.com/180742.
117 const base::Value* unused_value;
118 if (!params.Get("frame.parentId", &unused_value))
119 scheduled_frame_set_.clear();
120 }
121 }
OLDNEW
« no previous file with comments | « chrome/test/chromedriver/navigation_tracker.h ('k') | chrome/test/chromedriver/navigation_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698