Commit 33ef938e authored by kkania@chromium.org's avatar kkania@chromium.org

Add chrome.loadAsync capability to ChromeDriver, which allows the user not to

wait for page loads.
Also, be able to launch chromium and chrome regardless of what branding
we're built with.
BUG=89757
TEST=none


Review URL: http://codereview.chromium.org/7582005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96265 0039d316-1c4b-4281-b951-d872f2087c98
parent b4939695
...@@ -866,6 +866,7 @@ ...@@ -866,6 +866,7 @@
'test/webdriver/session_manager.cc', 'test/webdriver/session_manager.cc',
'test/webdriver/utility_functions.h', 'test/webdriver/utility_functions.h',
'test/webdriver/utility_functions.cc', 'test/webdriver/utility_functions.cc',
'test/webdriver/utility_functions_mac.mm',
'test/webdriver/webdriver_error.h', 'test/webdriver/webdriver_error.h',
'test/webdriver/webdriver_error.cc', 'test/webdriver/webdriver_error.cc',
'test/webdriver/webdriver_logging.h', 'test/webdriver/webdriver_logging.h',
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#endif #endif
#include "base/base_paths.h" #include "base/base_paths.h"
#include "base/basictypes.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/environment.h" #include "base/environment.h"
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
#include "base/file_util.h" #include "base/file_util.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/string_number_conversions.h" #include "base/string_number_conversions.h"
#include "base/string_split.h" #include "base/string_split.h"
...@@ -29,9 +31,12 @@ ...@@ -29,9 +31,12 @@
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/test/automation/automation_json_requests.h" #include "chrome/test/automation/automation_json_requests.h"
#include "chrome/test/automation/automation_proxy.h" #include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/extension_proxy.h" #include "chrome/test/automation/extension_proxy.h"
#include "chrome/test/automation/proxy_launcher.h" #include "chrome/test/automation/proxy_launcher.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/webdriver/frame_path.h" #include "chrome/test/webdriver/frame_path.h"
#include "chrome/test/webdriver/utility_functions.h"
#include "chrome/test/webdriver/webdriver_error.h" #include "chrome/test/webdriver/webdriver_error.h"
#include "ui/gfx/point.h" #include "ui/gfx/point.h"
...@@ -42,14 +47,71 @@ ...@@ -42,14 +47,71 @@
namespace { namespace {
// Iterates through each browser executable path, and checks if the path exists
// in any of the given locations. If found, returns true and sets |browser_exe|.
bool CheckForChromeExe(const std::vector<FilePath>& browser_exes,
const std::vector<FilePath>& locations,
FilePath* browser_exe) {
for (size_t i = 0; i < browser_exes.size(); ++i) {
for (size_t j = 0; j < locations.size(); ++j) {
FilePath path = locations[j].Append(browser_exes[i]);
if (file_util::PathExists(path)) {
*browser_exe = path;
return true;
}
}
}
return false;
}
// Gets the path to the default Chrome executable. Returns true on success. // Gets the path to the default Chrome executable. Returns true on success.
bool GetDefaultChromeExe(FilePath* browser_exe) { bool GetDefaultChromeExe(FilePath* browser_exe) {
std::vector<FilePath> locations; // Instead of using chrome constants, we hardcode these constants here so
// Add the directory which this module resides in. // that we can locate chrome or chromium regardless of the branding
// chromedriver is built with. It may be argued that then we need to keep
// these in sync with chrome constants. However, if chrome constants changes,
// we need to look for the previous and new versions to support some
// backwards compatibility.
#if defined(OS_WIN)
FilePath browser_exes_array[] = {
FilePath(L"chrome.exe")
};
#elif defined(OS_MACOSX)
FilePath browser_exes_array[] = {
FilePath("Google Chrome.app/Contents/MacOS/Google Chrome"),
FilePath("Chromium.app/Contents/MacOS/Chromium")
};
#elif defined(OS_LINUX)
FilePath browser_exes_array[] = {
FilePath("google-chrome"),
FilePath("chrome"),
FilePath("chromium"),
FilePath("chromium-browser")
};
#endif
std::vector<FilePath> browser_exes(
browser_exes_array, browser_exes_array + arraysize(browser_exes_array));
// Step 1: Check the directory this module resides in. This is done
// before all else so that the tests will pickup the built chrome.
FilePath module_dir; FilePath module_dir;
if (PathService::Get(base::DIR_MODULE, &module_dir)) if (PathService::Get(base::DIR_MODULE, &module_dir)) {
locations.push_back(module_dir); for (size_t j = 0; j < browser_exes.size(); ++j) {
FilePath path = module_dir.Append(browser_exes[j]);
if (file_util::PathExists(path)) {
*browser_exe = path;
return true;
}
}
}
// Step 2: Add all possible install locations, in order they should be
// searched. If a location can only hold a chromium install, add it to
// |chromium_locations|. Since on some platforms we cannot tell by the binary
// name whether it is chrome or chromium, we search these locations last.
// We attempt to run chrome before chromium, if any install can be found.
std::vector<FilePath> locations;
std::vector<FilePath> chromium_locations;
#if defined(OS_WIN) #if defined(OS_WIN)
// Add the App Paths registry key location. // Add the App Paths registry key location.
const wchar_t kSubKey[] = const wchar_t kSubKey[] =
...@@ -64,6 +126,7 @@ bool GetDefaultChromeExe(FilePath* browser_exe) { ...@@ -64,6 +126,7 @@ bool GetDefaultChromeExe(FilePath* browser_exe) {
// Add the user-level location for Chrome. // Add the user-level location for Chrome.
FilePath app_from_google(L"Google\\Chrome\\Application"); FilePath app_from_google(L"Google\\Chrome\\Application");
FilePath app_from_chromium(L"Chromium\\Application");
scoped_ptr<base::Environment> env(base::Environment::Create()); scoped_ptr<base::Environment> env(base::Environment::Create());
std::string home_dir; std::string home_dir;
if (env->GetVar("userprofile", &home_dir)) { if (env->GetVar("userprofile", &home_dir)) {
...@@ -75,6 +138,7 @@ bool GetDefaultChromeExe(FilePath* browser_exe) { ...@@ -75,6 +138,7 @@ bool GetDefaultChromeExe(FilePath* browser_exe) {
default_location = default_location.Append(L"AppData\\Local"); default_location = default_location.Append(L"AppData\\Local");
} }
locations.push_back(default_location.Append(app_from_google)); locations.push_back(default_location.Append(app_from_google));
chromium_locations.push_back(default_location.Append(app_from_chromium));
} }
// Add the system-level location for Chrome. // Add the system-level location for Chrome.
...@@ -82,22 +146,27 @@ bool GetDefaultChromeExe(FilePath* browser_exe) { ...@@ -82,22 +146,27 @@ bool GetDefaultChromeExe(FilePath* browser_exe) {
if (env->GetVar("ProgramFiles", &program_dir)) { if (env->GetVar("ProgramFiles", &program_dir)) {
locations.push_back(FilePath(UTF8ToWide(program_dir)) locations.push_back(FilePath(UTF8ToWide(program_dir))
.Append(app_from_google)); .Append(app_from_google));
chromium_locations.push_back(FilePath(UTF8ToWide(program_dir))
.Append(app_from_chromium));
} }
if (env->GetVar("ProgramFiles(x86)", &program_dir)) { if (env->GetVar("ProgramFiles(x86)", &program_dir)) {
locations.push_back(FilePath(UTF8ToWide(program_dir)) locations.push_back(FilePath(UTF8ToWide(program_dir))
.Append(app_from_google)); .Append(app_from_google));
chromium_locations.push_back(FilePath(UTF8ToWide(program_dir))
.Append(app_from_chromium));
} }
#elif defined(OS_MACOSX) #elif defined(OS_MACOSX)
locations.push_back(FilePath("/Applications")); std::vector<FilePath> app_dirs;
webdriver::GetApplicationDirs(&app_dirs);
locations.insert(locations.end(), app_dirs.begin(), app_dirs.end());
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
// Proxy launcher doesn't check for google-chrome, only chrome. locations.push_back(FilePath("/opt/google/chrome"));
FilePath chrome_sym_link("/usr/bin/google-chrome"); locations.push_back(FilePath("/usr/local/bin"));
if (file_util::PathExists(chrome_sym_link)) { locations.push_back(FilePath("/usr/local/sbin"));
FilePath chrome; locations.push_back(FilePath("/usr/bin"));
if (file_util::ReadSymbolicLink(chrome_sym_link, &chrome)) { locations.push_back(FilePath("/usr/sbin"));
locations.push_back(chrome.DirName()); locations.push_back(FilePath("/bin"));
} locations.push_back(FilePath("/sbin"));
}
#endif #endif
// Add the current directory. // Add the current directory.
...@@ -105,15 +174,10 @@ bool GetDefaultChromeExe(FilePath* browser_exe) { ...@@ -105,15 +174,10 @@ bool GetDefaultChromeExe(FilePath* browser_exe) {
if (file_util::GetCurrentDirectory(&current_dir)) if (file_util::GetCurrentDirectory(&current_dir))
locations.push_back(current_dir); locations.push_back(current_dir);
// Determine the default directory. // Step 3: For each browser exe path, check each location to see if the
for (size_t i = 0; i < locations.size(); ++i) { // browser is installed there. Check the chromium locations lastly.
FilePath path = locations[i].Append(chrome::kBrowserProcessExecutablePath); return CheckForChromeExe(browser_exes, locations, browser_exe) ||
if (file_util::PathExists(path)) { CheckForChromeExe(browser_exes, chromium_locations, browser_exe);
*browser_exe = path;
return true;
}
}
return false;
} }
} // namespace } // namespace
...@@ -430,6 +494,30 @@ void Automation::NavigateToURL(int tab_id, ...@@ -430,6 +494,30 @@ void Automation::NavigateToURL(int tab_id,
*error = new Error(kUnknownError, "Navigation error occurred"); *error = new Error(kUnknownError, "Navigation error occurred");
} }
void Automation::NavigateToURLAsync(int tab_id,
const std::string& url,
Error** error) {
int windex = 0, tab_index = 0;
*error = GetIndicesForTab(tab_id, &windex, &tab_index);
if (*error)
return;
scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(windex);
if (!browser) {
*error = new Error(kUnknownError, "Couldn't obtain browser proxy");
return;
}
scoped_refptr<TabProxy> tab = browser->GetTab(tab_index);
if (!tab) {
*error = new Error(kUnknownError, "Couldn't obtain tab proxy");
return;
}
if (!tab->NavigateToURLAsync(GURL(url))) {
*error = new Error(kUnknownError, "Unable to navigate to url");
return;
}
}
void Automation::GoForward(int tab_id, Error** error) { void Automation::GoForward(int tab_id, Error** error) {
int windex = 0, tab_index = 0; int windex = 0, tab_index = 0;
*error = GetIndicesForTab(tab_id, &windex, &tab_index); *error = GetIndicesForTab(tab_id, &windex, &tab_index);
......
...@@ -93,6 +93,7 @@ class Automation { ...@@ -93,6 +93,7 @@ class Automation {
void CaptureEntirePageAsPNG(int tab_id, const FilePath& path, Error** error); void CaptureEntirePageAsPNG(int tab_id, const FilePath& path, Error** error);
void NavigateToURL(int tab_id, const std::string& url, Error** error); void NavigateToURL(int tab_id, const std::string& url, Error** error);
void NavigateToURLAsync(int tab_id, const std::string& url, Error** error);
void GoForward(int tab_id, Error** error); void GoForward(int tab_id, Error** error);
void GoBack(int tab_id, Error** error); void GoBack(int tab_id, Error** error);
void Reload(int tab_id, Error** error); void Reload(int tab_id, Error** error);
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "chrome/test/webdriver/session_manager.h" #include "chrome/test/webdriver/session_manager.h"
#include "chrome/test/webdriver/webdriver_error.h" #include "chrome/test/webdriver/webdriver_error.h"
namespace webdriver {
namespace { namespace {
bool WriteBase64DataToFile(const FilePath& filename, bool WriteBase64DataToFile(const FilePath& filename,
...@@ -42,9 +44,18 @@ bool WriteBase64DataToFile(const FilePath& filename, ...@@ -42,9 +44,18 @@ bool WriteBase64DataToFile(const FilePath& filename,
return true; return true;
} }
} // namespace Error* GetBooleanCapability(
const base::DictionaryValue* dict, const std::string& key, bool* option) {
Value* value = NULL;
if (dict->GetWithoutPathExpansion(key, &value)) {
if (!value->GetAsBoolean(option)) {
return new Error(kUnknownError, key + " must be a boolean");
}
}
return NULL;
}
namespace webdriver { } // namespace
CreateSession::CreateSession(const std::vector<std::string>& path_segments, CreateSession::CreateSession(const std::vector<std::string>& path_segments,
const DictionaryValue* const parameters) const DictionaryValue* const parameters)
...@@ -175,11 +186,24 @@ void CreateSession::ExecutePost(Response* const response) { ...@@ -175,11 +186,24 @@ void CreateSession::ExecutePost(Response* const response) {
return; return;
} }
Session::Options options;
Error* error = NULL;
error = GetBooleanCapability(capabilities, "chrome.nativeEvents",
&options.use_native_events);
if (!error) {
error = GetBooleanCapability(capabilities, "chrome.loadAsync",
&options.load_async);
}
if (error) {
response->SetError(error);
return;
}
// Session manages its own liftime, so do not call delete. // Session manages its own liftime, so do not call delete.
Session* session = new Session(); Session* session = new Session(options);
Error* error = session->Init(browser_exe, error = session->Init(browser_exe,
temp_user_data_dir, temp_user_data_dir,
command_line_options); command_line_options);
if (error) { if (error) {
response->SetError(error); response->SetError(error);
return; return;
...@@ -194,20 +218,6 @@ void CreateSession::ExecutePost(Response* const response) { ...@@ -194,20 +218,6 @@ void CreateSession::ExecutePost(Response* const response) {
} }
} }
bool native_events_required = false;
Value* native_events_value = NULL;
if (capabilities->GetWithoutPathExpansion(
"chrome.nativeEvents", &native_events_value)) {
if (native_events_value->GetAsBoolean(&native_events_required)) {
session->set_use_native_events(native_events_required);
}
}
bool screenshot_on_error = false;
if (capabilities->GetBoolean(
"takeScreenshotOnError", &screenshot_on_error)) {
session->set_screenshot_on_error(screenshot_on_error);
}
LOG(INFO) << "Created session " << session->id(); LOG(INFO) << "Created session " << session->id();
// Redirect to a relative URI. Although prohibited by the HTTP standard, // Redirect to a relative URI. Although prohibited by the HTTP standard,
// this is what the IEDriver does. Finding the actual IP address is // this is what the IEDriver does. Finding the actual IP address is
......
...@@ -56,13 +56,11 @@ void SessionWithID::ExecuteGet(Response* const response) { ...@@ -56,13 +56,11 @@ void SessionWithID::ExecuteGet(Response* const response) {
// Custom non-standard session info. // Custom non-standard session info.
temp_value->SetWithoutPathExpansion( temp_value->SetWithoutPathExpansion(
"chrome.chromedriverVersion", Value::CreateStringValue("1.0")); "chrome.chromedriverVersion",
temp_value->SetWithoutPathExpansion(
"chrome.automationVersion",
Value::CreateStringValue(chrome::kChromeVersion)); Value::CreateStringValue(chrome::kChromeVersion));
temp_value->SetWithoutPathExpansion( temp_value->SetWithoutPathExpansion(
"chrome.nativeEvents", "chrome.nativeEvents",
Value::CreateBooleanValue(session_->use_native_events())); Value::CreateBooleanValue(session_->options().use_native_events));
response->SetValue(temp_value); response->SetValue(temp_value);
} }
......
...@@ -50,7 +50,8 @@ void AssertTimeoutSet(const Session& test_session, int expected_timeout, ...@@ -50,7 +50,8 @@ void AssertTimeoutSet(const Session& test_session, int expected_timeout,
} // namespace } // namespace
TEST(ImplicitWaitCommandTest, SettingImplicitWaits) { TEST(ImplicitWaitCommandTest, SettingImplicitWaits) {
Session test_session; Session::Options options = Session::Options();
Session test_session(options);
ASSERT_EQ(0, test_session.implicit_wait()) << "Sanity check failed"; ASSERT_EQ(0, test_session.implicit_wait()) << "Sanity check failed";
std::vector<std::string> path_segments; std::vector<std::string> path_segments;
......
...@@ -41,19 +41,11 @@ bool WebDriverCommand::Init(Response* const response) { ...@@ -41,19 +41,11 @@ bool WebDriverCommand::Init(Response* const response) {
return false; return false;
} }
LOG(INFO) << "Waiting for the page to stop loading"; Error* error = session_->BeforeExecuteCommand();
Error* error = session_->WaitForAllTabsToStopLoading();
if (error) { if (error) {
response->SetError(error); response->SetError(error);
return false; return false;
} }
LOG(INFO) << "Done waiting for the page to stop loading";
error = session_->SwitchToTopFrameIfCurrentFrameInvalid();
if (error) {
response->SetError(error);
return false;
}
response->SetField("sessionId", Value::CreateStringValue(session_id)); response->SetField("sessionId", Value::CreateStringValue(session_id));
return true; return true;
} }
......
...@@ -54,15 +54,22 @@ FrameId& FrameId::operator=(const FrameId& other) { ...@@ -54,15 +54,22 @@ FrameId& FrameId::operator=(const FrameId& other) {
return *this; return *this;
} }
Session::Session() Session::Options::Options()
: use_native_events(false),
load_async(false) {
}
Session::Options::~Options() {
}
Session::Session(const Options& options)
: id_(GenerateRandomID()), : id_(GenerateRandomID()),
current_target_(FrameId(0, FramePath())), current_target_(FrameId(0, FramePath())),
thread_(id_.c_str()), thread_(id_.c_str()),
async_script_timeout_(0), async_script_timeout_(0),
implicit_wait_(0), implicit_wait_(0),
screenshot_on_error_(false), has_alert_prompt_text_(false),
use_native_events_(false), options_(options) {
has_alert_prompt_text_(false) {
SessionManager::GetInstance()->Add(this); SessionManager::GetInstance()->Add(this);
} }
...@@ -91,6 +98,19 @@ Error* Session::Init(const FilePath& browser_exe, ...@@ -91,6 +98,19 @@ Error* Session::Init(const FilePath& browser_exe,
return error; return error;
} }
Error* Session::BeforeExecuteCommand() {
Error* error = NULL;
if (!options_.load_async) {
LOG(INFO) << "Waiting for the page to stop loading";
error = WaitForAllTabsToStopLoading();
LOG(INFO) << "Done waiting for the page to stop loading";
}
if (!error) {
error = SwitchToTopFrameIfCurrentFrameInvalid();
}
return error;
}
void Session::Terminate() { void Session::Terminate() {
RunSessionTask(NewRunnableMethod( RunSessionTask(NewRunnableMethod(
this, this,
...@@ -228,12 +248,21 @@ Error* Session::DragAndDropFilePaths( ...@@ -228,12 +248,21 @@ Error* Session::DragAndDropFilePaths(
Error* Session::NavigateToURL(const std::string& url) { Error* Session::NavigateToURL(const std::string& url) {
Error* error = NULL; Error* error = NULL;
RunSessionTask(NewRunnableMethod( if (options_.load_async) {
automation_.get(), RunSessionTask(NewRunnableMethod(
&Automation::NavigateToURL, automation_.get(),
current_target_.window_id, &Automation::NavigateToURLAsync,
url, current_target_.window_id,
&error)); url,
&error));
} else {
RunSessionTask(NewRunnableMethod(
automation_.get(),
&Automation::NavigateToURL,
current_target_.window_id,
url,
&error));
}
return error; return error;
} }
...@@ -1070,26 +1099,14 @@ int Session::implicit_wait() const { ...@@ -1070,26 +1099,14 @@ int Session::implicit_wait() const {
return implicit_wait_; return implicit_wait_;
} }
void Session::set_screenshot_on_error(bool error) {
screenshot_on_error_ = error;
}
bool Session::screenshot_on_error() const {
return screenshot_on_error_;
}
void Session::set_use_native_events(bool use_native_events) {
use_native_events_ = use_native_events;
}
bool Session::use_native_events() const {
return use_native_events_;
}
const gfx::Point& Session::get_mouse_position() const { const gfx::Point& Session::get_mouse_position() const {
return mouse_position_; return mouse_position_;
} }
const Session::Options& Session::options() const {
return options_;
}
void Session::RunSessionTask(Task* task) { void Session::RunSessionTask(Task* task) {
base::WaitableEvent done_event(false, false); base::WaitableEvent done_event(false, false);
thread_.message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod( thread_.message_loop_proxy()->PostTask(FROM_HERE, NewRunnableMethod(
...@@ -1197,7 +1214,7 @@ void Session::SendKeysOnSessionThread(const string16& keys, Error** error) { ...@@ -1197,7 +1214,7 @@ void Session::SendKeysOnSessionThread(const string16& keys, Error** error) {
return; return;
} }
for (size_t i = 0; i < key_events.size(); ++i) { for (size_t i = 0; i < key_events.size(); ++i) {
if (use_native_events_) { if (options_.use_native_events) {
// The automation provider will generate up/down events for us, we // The automation provider will generate up/down events for us, we
// only need to call it once as compared to the WebKeyEvent method. // only need to call it once as compared to the WebKeyEvent method.
// Hence we filter events by their types, keeping only rawkeydown. // Hence we filter events by their types, keeping only rawkeydown.
......
...@@ -53,9 +53,23 @@ struct FrameId { ...@@ -53,9 +53,23 @@ struct FrameId {
// A session manages its own lifetime. // A session manages its own lifetime.
class Session { class Session {
public: public:
struct Options {
Options();
~Options();
// True if the session should simulate OS-level input. Currently only
// applies to keyboard input.
bool use_native_events;
// True if the session should not wait for page loads and navigate
// asynchronously.
bool load_async;
};
// Adds this |Session| to the |SessionManager|. The session manages its own // Adds this |Session| to the |SessionManager|. The session manages its own
// lifetime. Do not call delete. // lifetime. Do not call delete.
Session(); explicit Session(const Options& options);
// Removes this |Session| from the |SessionManager|. // Removes this |Session| from the |SessionManager|.
~Session(); ~Session();
...@@ -69,6 +83,10 @@ class Session { ...@@ -69,6 +83,10 @@ class Session {
const FilePath& user_data_dir, const FilePath& user_data_dir,
const CommandLine& options); const CommandLine& options);
// Should be called before executing a command. Performs necessary waits
// and frame switching.
Error* BeforeExecuteCommand();
// Terminates this session and deletes itself. // Terminates this session and deletes itself.
void Terminate(); void Terminate();
...@@ -296,14 +314,10 @@ class Session { ...@@ -296,14 +314,10 @@ class Session {
void set_implicit_wait(int timeout_ms); void set_implicit_wait(int timeout_ms);
int implicit_wait() const; int implicit_wait() const;
void set_screenshot_on_error(bool error);
bool screenshot_on_error() const;
void set_use_native_events(bool use_native_events);
bool use_native_events() const;
const gfx::Point& get_mouse_position() const; const gfx::Point& get_mouse_position() const;
const Options& options() const;
private: private:
void RunSessionTask(Task* task); void RunSessionTask(Task* task);
void RunSessionTaskOnSessionThread( void RunSessionTaskOnSessionThread(
...@@ -357,15 +371,6 @@ class Session { ...@@ -357,15 +371,6 @@ class Session {
// Time (in ms) of how long to wait while searching for a single element. // Time (in ms) of how long to wait while searching for a single element.
int implicit_wait_; int implicit_wait_;
// Since screenshots can be very large when in base64 PNG format; the
// client is allowed to dyamically enable/disable screenshots on error
// during the lifetime of the session.
bool screenshot_on_error_;
// True if the session should simulate OS-level input. Currently only applies
// to keyboard input.
bool use_native_events_;
// Vector of the |WebElementId|s for each frame of the current target frame // Vector of the |WebElementId|s for each frame of the current target frame
// path. The first refers to the first frame element in the root document. // path. The first refers to the first frame element in the root document.
// If the target frame is window.top, this will be empty. // If the target frame is window.top, this will be empty.
...@@ -382,6 +387,8 @@ class Session { ...@@ -382,6 +387,8 @@ class Session {
std::string alert_prompt_text_; std::string alert_prompt_text_;
bool has_alert_prompt_text_; bool has_alert_prompt_text_;
Options options_;
DISALLOW_COPY_AND_ASSIGN(Session); DISALLOW_COPY_AND_ASSIGN(Session);
}; };
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#define CHROME_TEST_WEBDRIVER_UTILITY_FUNCTIONS_H_ #define CHROME_TEST_WEBDRIVER_UTILITY_FUNCTIONS_H_
#include <string> #include <string>
#include <vector>
class FilePath;
namespace base { namespace base {
class Value; class Value;
...@@ -19,6 +22,11 @@ std::string GenerateRandomID(); ...@@ -19,6 +22,11 @@ std::string GenerateRandomID();
// Returns the equivalent JSON string for the given value. // Returns the equivalent JSON string for the given value.
std::string JsonStringify(const base::Value* value); std::string JsonStringify(const base::Value* value);
#if defined(OS_MACOSX)
// Gets the paths to the user and local application directory.
void GetApplicationDirs(std::vector<FilePath>* app_dirs);
#endif
} // namespace webdriver } // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_UTILITY_FUNCTIONS_H_ #endif // CHROME_TEST_WEBDRIVER_UTILITY_FUNCTIONS_H_
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/test/webdriver/utility_functions.h"
#import <Foundation/Foundation.h>
#include "base/file_path.h"
#include "base/mac/foundation_util.h"
namespace webdriver {
void GetApplicationDirs(std::vector<FilePath>* app_dirs) {
FilePath user_app_dir;
if (base::mac::GetUserDirectory(NSApplicationDirectory, &user_app_dir))
app_dirs->push_back(user_app_dir);
FilePath local_app_dir;
if (base::mac::GetLocalDirectory(NSApplicationDirectory, &local_app_dir))
app_dirs->push_back(local_app_dir);
}
} // namespace webdriver
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