1// Copyright (c) 2012 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/session.h"
6
7#include <list>
8
9#include "base/lazy_instance.h"
10#include "base/threading/thread_local.h"
11#include "base/values.h"
12#include "chrome/test/chromedriver/chrome/chrome.h"
13#include "chrome/test/chromedriver/chrome/status.h"
14#include "chrome/test/chromedriver/chrome/web_view.h"
15#include "chrome/test/chromedriver/logging.h"
16
17namespace {
18
19base::LazyInstance<base::ThreadLocalPointer<Session> >
20    lazy_tls_session = LAZY_INSTANCE_INITIALIZER;
21
22}  // namespace
23
24FrameInfo::FrameInfo(const std::string& parent_frame_id,
25                     const std::string& frame_id,
26                     const std::string& chromedriver_frame_id)
27    : parent_frame_id(parent_frame_id),
28      frame_id(frame_id),
29      chromedriver_frame_id(chromedriver_frame_id) {}
30
31const base::TimeDelta Session::kDefaultPageLoadTimeout =
32    base::TimeDelta::FromMinutes(5);
33
34Session::Session(const std::string& id)
35    : id(id),
36      quit(false),
37      detach(false),
38      force_devtools_screenshot(false),
39      sticky_modifiers(0),
40      mouse_position(0, 0),
41      page_load_timeout(kDefaultPageLoadTimeout),
42      auto_reporting_enabled(false) {}
43
44Session::Session(const std::string& id, scoped_ptr<Chrome> chrome)
45    : id(id),
46      quit(false),
47      detach(false),
48      force_devtools_screenshot(false),
49      chrome(chrome.Pass()),
50      sticky_modifiers(0),
51      mouse_position(0, 0),
52      page_load_timeout(kDefaultPageLoadTimeout),
53      auto_reporting_enabled(false) {}
54
55Session::~Session() {}
56
57Status Session::GetTargetWindow(WebView** web_view) {
58  if (!chrome)
59    return Status(kNoSuchWindow, "no chrome started in this session");
60
61  Status status = chrome->GetWebViewById(window, web_view);
62  if (status.IsError())
63    status = Status(kNoSuchWindow, "target window already closed", status);
64  return status;
65}
66
67void Session::SwitchToTopFrame() {
68  frames.clear();
69}
70
71void Session::SwitchToParentFrame() {
72  if (!frames.empty())
73    frames.pop_back();
74}
75
76void Session::SwitchToSubFrame(const std::string& frame_id,
77                               const std::string& chromedriver_frame_id) {
78  std::string parent_frame_id;
79  if (!frames.empty())
80    parent_frame_id = frames.back().frame_id;
81  frames.push_back(FrameInfo(parent_frame_id, frame_id, chromedriver_frame_id));
82}
83
84std::string Session::GetCurrentFrameId() const {
85  if (frames.empty())
86    return std::string();
87  return frames.back().frame_id;
88}
89
90std::vector<WebDriverLog*> Session::GetAllLogs() const {
91  std::vector<WebDriverLog*> logs;
92  for (ScopedVector<WebDriverLog>::const_iterator log = devtools_logs.begin();
93       log != devtools_logs.end();
94       ++log) {
95    logs.push_back(*log);
96  }
97  if (driver_log)
98    logs.push_back(driver_log.get());
99  return logs;
100}
101
102std::string Session::GetFirstBrowserError() const {
103  for (ScopedVector<WebDriverLog>::const_iterator it = devtools_logs.begin();
104       it != devtools_logs.end();
105       ++it) {
106    if ((*it)->type() == WebDriverLog::kBrowserType) {
107      std::string message = (*it)->GetFirstErrorMessage();
108      if (!message.empty())
109        return message;
110    }
111  }
112  return std::string();
113}
114
115Session* GetThreadLocalSession() {
116  return lazy_tls_session.Pointer()->Get();
117}
118
119void SetThreadLocalSession(scoped_ptr<Session> session) {
120  lazy_tls_session.Pointer()->Set(session.release());
121}
122