| Index: chrome/test/chromedriver/chrome_impl.cc
|
| diff --git a/chrome/test/chromedriver/chrome_impl.cc b/chrome/test/chromedriver/chrome_impl.cc
|
| index 5cac6f34942f6e6cc97bbd312d3b69788a958995..f074d3c52759fb7017c1bbcd344bcb56fe6abee1 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
|
|
|