summaryrefslogtreecommitdiffstats
path: root/chrome/test/chromedriver/chrome_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/test/chromedriver/chrome_impl.cc')
-rw-r--r--chrome/test/chromedriver/chrome_impl.cc82
1 files changed, 80 insertions, 2 deletions
diff --git a/chrome/test/chromedriver/chrome_impl.cc b/chrome/test/chromedriver/chrome_impl.cc
index 5cac6f3..f074d3c 100644
--- a/chrome/test/chromedriver/chrome_impl.cc
+++ b/chrome/test/chromedriver/chrome_impl.cc
@@ -4,13 +4,42 @@
#include "chrome/test/chromedriver/chrome_impl.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/process_util.h"
+#include "base/stringprintf.h"
+#include "base/threading/platform_thread.h"
+#include "base/time.h"
+#include "base/values.h"
+#include "chrome/test/chromedriver/devtools_client.h"
+#include "chrome/test/chromedriver/net/net_util.h"
+#include "chrome/test/chromedriver/net/url_request_context_getter.h"
#include "chrome/test/chromedriver/status.h"
+#include "googleurl/src/gurl.h"
+
+namespace {
+
+Status FetchPagesInfo(URLRequestContextGetter* context_getter,
+ int port,
+ std::list<std::string>* debugger_urls) {
+ std::string url = base::StringPrintf(
+ "http://127.0.0.1:%d/json", port);
+ std::string data;
+ if (!FetchUrl(GURL(url), context_getter, &data))
+ return Status(kChromeNotReachable);
+ return internal::ParsePagesInfo(data, debugger_urls);
+}
+
+} // namespace
ChromeImpl::ChromeImpl(base::ProcessHandle process,
- base::ScopedTempDir* user_data_dir)
- : process_(process) {
+ URLRequestContextGetter* context_getter,
+ base::ScopedTempDir* user_data_dir,
+ int port)
+ : process_(process),
+ context_getter_(context_getter),
+ port_(port) {
if (user_data_dir->IsValid()) {
CHECK(user_data_dir_.Set(user_data_dir->Take()));
}
@@ -20,8 +49,57 @@ ChromeImpl::~ChromeImpl() {
base::CloseProcessHandle(process_);
}
+Status ChromeImpl::Init() {
+ base::Time deadline = base::Time::Now() + base::TimeDelta::FromSeconds(20);
+ std::list<std::string> debugger_urls;
+ while (base::Time::Now() < deadline) {
+ FetchPagesInfo(context_getter_, port_, &debugger_urls);
+ if (debugger_urls.empty())
+ base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
+ else
+ break;
+ }
+ if (debugger_urls.empty())
+ return Status(kUnknownError, "unable to discover open pages");
+ client_.reset(new DevToolsClient(context_getter_, debugger_urls.front()));
+ return Status(kOk);
+}
+
+Status ChromeImpl::Load(const std::string& url) {
+ base::DictionaryValue params;
+ params.SetString("url", url);
+ return client_->SendCommand("Page.navigate", params);
+}
+
Status ChromeImpl::Quit() {
if (!base::KillProcess(process_, 0, true))
return Status(kUnknownError, "cannot kill Chrome");
return Status(kOk);
}
+
+namespace internal {
+
+Status ParsePagesInfo(const std::string& data,
+ std::list<std::string>* debugger_urls) {
+ scoped_ptr<base::Value> value(base::JSONReader::Read(data));
+ if (!value.get())
+ return Status(kUnknownError, "DevTools returned invalid JSON");
+ base::ListValue* list;
+ if (!value->GetAsList(&list))
+ return Status(kUnknownError, "DevTools did not return list");
+
+ std::list<std::string> internal_urls;
+ for (size_t i = 0; i < list->GetSize(); ++i) {
+ base::DictionaryValue* info;
+ if (!list->GetDictionary(i, &info))
+ return Status(kUnknownError, "DevTools contains non-dictionary item");
+ std::string debugger_url;
+ if (!info->GetString("webSocketDebuggerUrl", &debugger_url))
+ return Status(kUnknownError, "DevTools did not include debugger URL");
+ internal_urls.push_back(debugger_url);
+ }
+ debugger_urls->swap(internal_urls);
+ return Status(kOk);
+}
+
+} // namespace internal