blob: 910d1b5ab8d2a91fd1db13a97232ae769b60b86c [file] [log] [blame]
// Copyright 2011 Software Freedom Conservancy
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "IECommandExecutor.h"
#include "logging.h"
#include "CommandHandlers/AcceptAlertCommandHandler.h"
#include "CommandHandlers/AddCookieCommandHandler.h"
#include "CommandHandlers/ClickElementCommandHandler.h"
#include "CommandHandlers/ClearElementCommandHandler.h"
#include "CommandHandlers/CloseWindowCommandHandler.h"
#include "CommandHandlers/DeleteAllCookiesCommandHandler.h"
#include "CommandHandlers/DeleteCookieCommandHandler.h"
#include "CommandHandlers/DismissAlertCommandHandler.h"
#include "CommandHandlers/ElementEqualsCommandHandler.h"
#include "CommandHandlers/ExecuteAsyncScriptCommandHandler.h"
#include "CommandHandlers/ExecuteScriptCommandHandler.h"
#include "CommandHandlers/FindChildElementCommandHandler.h"
#include "CommandHandlers/FindChildElementsCommandHandler.h"
#include "CommandHandlers/FindElementCommandHandler.h"
#include "CommandHandlers/FindElementsCommandHandler.h"
#include "CommandHandlers/GetActiveElementCommandHandler.h"
#include "CommandHandlers/GetAlertTextCommandHandler.h"
#include "CommandHandlers/GetAllCookiesCommandHandler.h"
#include "CommandHandlers/GetAllWindowHandlesCommandHandler.h"
#include "CommandHandlers/GetCurrentUrlCommandHandler.h"
#include "CommandHandlers/GetCurrentWindowHandleCommandHandler.h"
#include "CommandHandlers/GetElementAttributeCommandHandler.h"
#include "CommandHandlers/GetElementLocationCommandHandler.h"
#include "CommandHandlers/GetElementLocationOnceScrolledIntoViewCommandHandler.h"
#include "CommandHandlers/GetElementSizeCommandHandler.h"
#include "CommandHandlers/GetElementTagNameCommandHandler.h"
#include "CommandHandlers/GetElementTextCommandHandler.h"
#include "CommandHandlers/GetElementValueOfCssPropertyCommandHandler.h"
#include "CommandHandlers/GetSessionCapabilitiesCommandHandler.h"
#include "CommandHandlers/GetPageSourceCommandHandler.h"
#include "CommandHandlers/GetTitleCommandHandler.h"
#include "CommandHandlers/GetWindowPositionCommandHandler.h"
#include "CommandHandlers/GetWindowSizeCommandHandler.h"
#include "CommandHandlers/GoBackCommandHandler.h"
#include "CommandHandlers/GoForwardCommandHandler.h"
#include "CommandHandlers/GoToUrlCommandHandler.h"
#include "CommandHandlers/IsElementDisplayedCommandHandler.h"
#include "CommandHandlers/IsElementEnabledCommandHandler.h"
#include "CommandHandlers/IsElementSelectedCommandHandler.h"
#include "CommandHandlers/MaximizeWindowCommandHandler.h"
#include "CommandHandlers/MouseMoveToCommandHandler.h"
#include "CommandHandlers/MouseClickCommandHandler.h"
#include "CommandHandlers/MouseDoubleClickCommandHandler.h"
#include "CommandHandlers/MouseButtonDownCommandHandler.h"
#include "CommandHandlers/MouseButtonUpCommandHandler.h"
#include "CommandHandlers/NewSessionCommandHandler.h"
#include "CommandHandlers/QuitCommandHandler.h"
#include "CommandHandlers/RefreshCommandHandler.h"
#include "CommandHandlers/ScreenshotCommandHandler.h"
#include "CommandHandlers/SendKeysCommandHandler.h"
#include "CommandHandlers/SendKeysToActiveElementCommandHandler.h"
#include "CommandHandlers/SendKeysToAlertCommandHandler.h"
#include "CommandHandlers/SetAsyncScriptTimeoutCommandHandler.h"
#include "CommandHandlers/SetImplicitWaitTimeoutCommandHandler.h"
#include "CommandHandlers/SetTimeoutCommandHandler.h"
#include "CommandHandlers/SetWindowPositionCommandHandler.h"
#include "CommandHandlers/SetWindowSizeCommandHandler.h"
#include "CommandHandlers/SubmitElementCommandHandler.h"
#include "CommandHandlers/SwitchToFrameCommandHandler.h"
#include "CommandHandlers/SwitchToWindowCommandHandler.h"
namespace webdriver {
LRESULT IECommandExecutor::OnInit(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnInit";
// If we wanted to be a little more clever, we could create a struct
// containing the HWND and the port number and pass them into the
// ThreadProc via lpParameter and avoid this message handler altogether.
this->port_ = (int)wParam;
return 0;
}
LRESULT IECommandExecutor::OnCreate(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnCreate";
// NOTE: COM should be initialized on this thread, so we
// could use CoCreateGuid() and StringFromGUID2() instead.
UUID guid;
RPC_WSTR guid_string = NULL;
RPC_STATUS status = ::UuidCreate(&guid);
status = ::UuidToString(&guid, &guid_string);
// RPC_WSTR is currently typedef'd in RpcDce.h (pulled in by rpc.h)
// as unsigned short*. It needs to be typedef'd as wchar_t*
wchar_t* cast_guid_string = reinterpret_cast<wchar_t*>(guid_string);
this->SetWindowText(cast_guid_string);
std::string session_id = CW2A(cast_guid_string, CP_UTF8);
this->session_id_ = session_id;
this->is_valid_ = true;
::RpcStringFree(&guid_string);
this->PopulateCommandHandlers();
this->PopulateElementFinderMethods();
this->current_browser_id_ = "";
this->serialized_response_ = "";
this->initial_browser_url_ = "";
this->ignore_protected_mode_settings_ = false;
this->ignore_zoom_setting_ = false;
this->enable_element_cache_cleanup_ = true;
this->enable_persistent_hover_ = true;
this->unexpected_alert_behavior_ = IGNORE_UNEXPECTED_ALERTS;
this->speed_ = 0;
this->implicit_wait_timeout_ = 0;
this->async_script_timeout_ = -1;
this->page_load_timeout_ = -1;
this->input_manager_ = new InputManager();
this->input_manager_->Initialize(&this->managed_elements_);
// Only execute atoms on a separate thread for IE 9 or below.
// Attempting this on IE 10 crashes unpredictably at the moment
// on Windows 8, and no one has a development environment available
// to debug the issue.
this->allow_asynchronous_javascript_ = this->factory_.browser_version() <= 9;
return 0;
}
LRESULT IECommandExecutor::OnClose(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnClose";
this->managed_elements_.Clear();
delete this->input_manager_;
this->DestroyWindow();
return 0;
}
LRESULT IECommandExecutor::OnDestroy(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnDestroy";
::PostQuitMessage(0);
return 0;
}
LRESULT IECommandExecutor::OnSetCommand(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnSetCommand";
LPCSTR json_command = reinterpret_cast<LPCSTR>(lParam);
this->current_command_.Populate(json_command);
return 0;
}
LRESULT IECommandExecutor::OnExecCommand(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnExecCommand";
this->DispatchCommand();
return 0;
}
LRESULT IECommandExecutor::OnGetResponseLength(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnGetResponseLength";
size_t response_length = 0;
if (!this->is_waiting_) {
response_length = this->serialized_response_.size();
}
return response_length;
}
LRESULT IECommandExecutor::OnGetResponse(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnGetResponse";
LPSTR str = reinterpret_cast<LPSTR>(lParam);
strcpy_s(str,
this->serialized_response_.size() + 1,
this->serialized_response_.c_str());
// Reset the serialized response for the next command.
this->serialized_response_ = "";
return 0;
}
LRESULT IECommandExecutor::OnWait(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnWait";
BrowserHandle browser;
int status_code = this->GetCurrentBrowser(&browser);
if (status_code == SUCCESS && !browser->is_closing()) {
if (this->page_load_timeout_ >= 0 && this->wait_timeout_ < clock()) {
Response timeout_response;
timeout_response.SetErrorResponse(ETIMEOUT, "Timed out waiting for page to load.");
this->serialized_response_ = timeout_response.Serialize();
this->is_waiting_ = false;
browser->set_wait_required(false);
} else {
this->is_waiting_ = !(browser->Wait());
if (this->is_waiting_) {
// If we are still waiting, we need to wait a bit then post a message to
// ourselves to run the wait again. However, we can't wait using Sleep()
// on this thread. This call happens in a message loop, and we would be
// unable to process the COM events in the browser if we put this thread
// to sleep.
unsigned int thread_id = 0;
HANDLE thread_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL,
0,
&IECommandExecutor::WaitThreadProc,
(void *)this->m_hWnd,
0,
&thread_id));
if (thread_handle != NULL) {
::CloseHandle(thread_handle);
}
}
}
} else {
this->is_waiting_ = false;
}
return 0;
}
LRESULT IECommandExecutor::OnBrowserNewWindow(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnBrowserNewWindow";
IWebBrowser2* browser = this->factory_.CreateBrowser();
BrowserHandle new_window_wrapper(new Browser(browser, NULL, this->m_hWnd));
this->AddManagedBrowser(new_window_wrapper);
LPSTREAM* stream = reinterpret_cast<LPSTREAM*>(lParam);
HRESULT hr = ::CoMarshalInterThreadInterfaceInStream(IID_IWebBrowser2,
browser,
stream);
return 0;
}
LRESULT IECommandExecutor::OnBrowserQuit(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnBrowserQuit";
LPCSTR str = reinterpret_cast<LPCSTR>(lParam);
std::string browser_id(str);
delete[] str;
BrowserMap::iterator found_iterator = this->managed_browsers_.find(browser_id);
if (found_iterator != this->managed_browsers_.end()) {
this->managed_browsers_.erase(browser_id);
if (this->managed_browsers_.size() == 0) {
this->current_browser_id_ = "";
}
} else {
LOG(WARN) << "Unable to find browser to quit with ID " << browser_id;
}
return 0;
}
LRESULT IECommandExecutor::OnIsSessionValid(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
LOG(TRACE) << "Entering IECommandExecutor::OnIsSessionValid";
return this->is_valid_ ? 1 : 0;
}
LRESULT IECommandExecutor::OnNewHtmlDialog(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandles) {
LOG(TRACE) << "Entering IECommandExecutor::OnNewHtmlDialog";
HWND dialog_handle = reinterpret_cast<HWND>(lParam);
BrowserMap::const_iterator it = this->managed_browsers_.begin();
for (; it != this->managed_browsers_.end(); ++it) {
if (dialog_handle == it->second->window_handle()) {
LOG(DEBUG) << "Dialog is equal to one managed browser";
return 0;
}
}
CComPtr<IHTMLDocument2> document;
if (this->factory_.GetDocumentFromWindowHandle(dialog_handle, &document)) {
CComPtr<IHTMLWindow2> window;
document->get_parentWindow(&window);
this->AddManagedBrowser(BrowserHandle(new HtmlDialog(window,
dialog_handle,
this->m_hWnd)));
} else {
LOG(WARN) << "Unable to get document from dialog";
}
return 0;
}
LRESULT IECommandExecutor::OnGetQuitStatus(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
return this->is_quitting_ && this->managed_browsers_.size() > 0 ? 1 : 0;
}
LRESULT IECommandExecutor::OnRefreshManagedElements(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
if (this->enable_element_cache_cleanup_) {
this->managed_elements_.ClearCache();
}
return 0;
}
unsigned int WINAPI IECommandExecutor::WaitThreadProc(LPVOID lpParameter) {
HWND window_handle = reinterpret_cast<HWND>(lpParameter);
::Sleep(WAIT_TIME_IN_MILLISECONDS);
::PostMessage(window_handle, WD_WAIT, NULL, NULL);
return 0;
}
unsigned int WINAPI IECommandExecutor::ThreadProc(LPVOID lpParameter) {
// Optional TODO: Create a struct to pass in via lpParameter
// instead of just a pointer to an HWND. That way, we could
// pass the mongoose server port via a single call, rather than
// having to send an init message after the window is created.
HWND *window_handle = reinterpret_cast<HWND*>(lpParameter);
DWORD error = 0;
HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
IECommandExecutor new_session;
HWND session_window_handle = new_session.Create(HWND_MESSAGE,
CWindow::rcDefault);
if (session_window_handle == NULL) {
error = ::GetLastError();
LOG(WARN) << "Unable to create new session: " << error;
}
MSG msg;
::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// Return the HWND back through lpParameter, and signal that the
// window is ready for messages.
*window_handle = session_window_handle;
HANDLE event_handle = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME);
if (event_handle != NULL) {
::SetEvent(event_handle);
::CloseHandle(event_handle);
}
// Run the message loop
while (::GetMessage(&msg, NULL, 0, 0) > 0) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::CoUninitialize();
return 0;
}
void IECommandExecutor::DispatchCommand() {
LOG(TRACE) << "Entering IECommandExecutor::DispatchCommand";
Response response(this->session_id_);
CommandHandlerMap::const_iterator found_iterator =
this->command_handlers_.find(this->current_command_.command_type());
if (found_iterator == this->command_handlers_.end()) {
LOG(WARN) << "Unable to find command handler for " << this->current_command_.command_type();
response.SetErrorResponse(501, "Command not implemented");
} else {
BrowserHandle browser;
int status_code = SUCCESS;
if (this->current_command_.command_type() != webdriver::CommandType::NewSession) {
// There should never be a modal dialog or alert to check for if the command
// is the "newSession" command.
status_code = this->GetCurrentBrowser(&browser);
if (status_code == SUCCESS) {
bool alert_is_active = false;
HWND alert_handle = browser->GetActiveDialogWindowHandle();
if (alert_handle != NULL) {
// Found a window handle, make sure it's an actual alert,
// and not a showModalDialog() window.
vector<char> window_class_name(34);
::GetClassNameA(alert_handle, &window_class_name[0], 34);
if (strcmp(ALERT_WINDOW_CLASS, &window_class_name[0]) == 0) {
alert_is_active = true;
} else {
LOG(WARN) << "Found alert handle does not have a window class consistent with an alert";
}
} else {
LOG(DEBUG) << "No alert handle is found";
}
if (alert_is_active) {
Alert dialog(browser, alert_handle);
std::string command_type = this->current_command_.command_type();
if (command_type == webdriver::CommandType::GetAlertText ||
command_type == webdriver::CommandType::SendKeysToAlert ||
command_type == webdriver::CommandType::AcceptAlert ||
command_type == webdriver::CommandType::DismissAlert) {
LOG(DEBUG) << "Alert is detected, and the sent command is valid";
} else {
LOG(DEBUG) << "Unexpected alert is detected, and the sent command is invalid when an alert is present";
std::string alert_text = dialog.GetText();
if (this->unexpected_alert_behavior_ == ACCEPT_UNEXPECTED_ALERTS) {
LOG(DEBUG) << "Automatically accepting the alert";
dialog.Accept();
} else if (this->unexpected_alert_behavior_ == DISMISS_UNEXPECTED_ALERTS || command_type == webdriver::CommandType::Quit) {
// If a quit command was issued, we should not ignore an unhandled
// alert, even if the alert behavior is set to "ignore".
LOG(DEBUG) << "Automatically dismissing the alert";
if (dialog.is_standard_alert()) {
dialog.Dismiss();
} else {
// The dialog was non-standard. The most common case of this is
// an onBeforeUnload dialog, which must be accepted to continue.
dialog.Accept();
}
}
if (command_type != webdriver::CommandType::Quit) {
// To keep pace with what Firefox does, we'll return the text of the
// alert in the error response.
Json::Value response_value;
response_value["message"] = "Modal dialog present";
response_value["alert"]["text"] = alert_text;
response.SetResponse(EMODALDIALOGOPENED, response_value);
this->serialized_response_ = response.Serialize();
return;
} else {
LOG(DEBUG) << "Quit command was issued. Continuing with command after automatically closing alert.";
}
}
}
} else {
LOG(WARN) << "Unable to find current browser";
}
}
CommandHandlerHandle command_handler = found_iterator->second;
command_handler->Execute(*this, this->current_command_, &response);
status_code = this->GetCurrentBrowser(&browser);
if (status_code == SUCCESS) {
this->is_waiting_ = browser->wait_required();
if (this->is_waiting_) {
if (this->page_load_timeout_ >= 0) {
this->wait_timeout_ = clock() + (this->page_load_timeout_ / 1000 * CLOCKS_PER_SEC);
}
::PostMessage(this->m_hWnd, WD_WAIT, NULL, NULL);
}
} else {
if (this->current_command_.command_type() != webdriver::CommandType::Quit) {
LOG(WARN) << "Unable to get current browser";
}
}
}
this->serialized_response_ = response.Serialize();
}
int IECommandExecutor::GetCurrentBrowser(BrowserHandle* browser_wrapper) const {
LOG(TRACE) << "Entering IECommandExecutor::GetCurrentBrowser";
return this->GetManagedBrowser(this->current_browser_id_, browser_wrapper);
}
int IECommandExecutor::GetManagedBrowser(const std::string& browser_id,
BrowserHandle* browser_wrapper) const {
LOG(TRACE) << "Entering IECommandExecutor::GetManagedBrowser";
if (!this->is_valid()) {
return ENOSUCHDRIVER;
}
if (browser_id == "") {
LOG(WARN) << "Browser ID requested was an empty string";
return ENOSUCHWINDOW;
}
BrowserMap::const_iterator found_iterator =
this->managed_browsers_.find(browser_id);
if (found_iterator == this->managed_browsers_.end()) {
LOG(WARN) << "Unable to find managed browser with id " << browser_id;
return ENOSUCHWINDOW;
}
*browser_wrapper = found_iterator->second;
return SUCCESS;
}
void IECommandExecutor::GetManagedBrowserHandles(std::vector<std::string>* managed_browser_handles) const {
LOG(TRACE) << "Entering IECommandExecutor::GetManagedBrowserHandles";
BrowserMap::const_iterator it = this->managed_browsers_.begin();
for (; it != this->managed_browsers_.end(); ++it) {
managed_browser_handles->push_back(it->first);
// Look for browser windows created by showModalDialog().
it->second->GetActiveDialogWindowHandle();
}
}
void IECommandExecutor::AddManagedBrowser(BrowserHandle browser_wrapper) {
LOG(TRACE) << "Entering IECommandExecutor::AddManagedBrowser";
this->managed_browsers_[browser_wrapper->browser_id()] = browser_wrapper;
if (this->current_browser_id_ == "") {
LOG(TRACE) << "Setting current browser id to " << browser_wrapper->browser_id();
this->current_browser_id_ = browser_wrapper->browser_id();
}
}
int IECommandExecutor::CreateNewBrowser(std::string* error_message) {
LOG(TRACE) << "Entering IECommandExecutor::CreateNewBrowser";
vector<char> port_buffer(10);
_itoa_s(this->port_, &port_buffer[0], 10, 10);
std::string port(&port_buffer[0]);
std::string initial_url = this->initial_browser_url_;
if (this->initial_browser_url_ == "") {
initial_url = "http://localhost:" + port + "/";
}
DWORD process_id = this->factory_.LaunchBrowserProcess(initial_url,
this->ignore_protected_mode_settings_, error_message);
if (process_id == NULL) {
LOG(WARN) << "Unable to launch browser, received NULL process ID";
this->is_waiting_ = false;
return ENOSUCHDRIVER;
}
ProcessWindowInfo process_window_info;
process_window_info.dwProcessId = process_id;
process_window_info.hwndBrowser = NULL;
process_window_info.pBrowser = NULL;
bool attached = this->factory_.AttachToBrowser(&process_window_info,
this->ignore_zoom_setting_,
error_message);
if (!attached) {
LOG(WARN) << "Unable to attach to browser COM object";
this->is_waiting_ = false;
return ENOSUCHDRIVER;
}
// Set persistent hover functionality in the interactions implementation.
setEnablePersistentHover(this->enable_persistent_hover_);
LOG(INFO) << "Persistent hovering set to: " << this->enable_persistent_hover_;
if (!this->enable_persistent_hover_) {
LOG(INFO) << "Stopping previously-running persistent event thread.";
stopPersistentEventFiring();
}
BrowserHandle wrapper(new Browser(process_window_info.pBrowser,
process_window_info.hwndBrowser,
this->m_hWnd));
this->AddManagedBrowser(wrapper);
return SUCCESS;
}
int IECommandExecutor::GetManagedElement(const std::string& element_id,
ElementHandle* element_wrapper) const {
LOG(TRACE) << "Entering IECommandExecutor::GetManagedElement";
return this->managed_elements_.GetManagedElement(element_id, element_wrapper);
}
void IECommandExecutor::AddManagedElement(IHTMLElement* element,
ElementHandle* element_wrapper) {
LOG(TRACE) << "Entering IECommandExecutor::AddManagedElement";
BrowserHandle current_browser;
this->GetCurrentBrowser(&current_browser);
this->managed_elements_.AddManagedElement(current_browser, element, element_wrapper);
}
void IECommandExecutor::RemoveManagedElement(const std::string& element_id) {
LOG(TRACE) << "Entering IECommandExecutor::RemoveManagedElement";
this->managed_elements_.RemoveManagedElement(element_id);
}
void IECommandExecutor::ListManagedElements() {
LOG(TRACE) << "Entering IECommandExecutor::ListManagedElements";
this->managed_elements_.ListManagedElements();
}
int IECommandExecutor::GetElementFindMethod(const std::string& mechanism,
std::wstring* translation) const {
LOG(TRACE) << "Entering IECommandExecutor::GetElementFindMethod";
ElementFindMethodMap::const_iterator found_iterator =
this->element_find_methods_.find(mechanism);
if (found_iterator == this->element_find_methods_.end()) {
LOG(WARN) << "Unable to determine find method " << mechanism;
return EUNHANDLEDERROR;
}
*translation = found_iterator->second;
return SUCCESS;
}
int IECommandExecutor::LocateElement(const ElementHandle parent_wrapper,
const std::string& mechanism,
const std::string& criteria,
Json::Value* found_element) const {
LOG(TRACE) << "Entering IECommandExecutor::LocateElement";
std::wstring mechanism_translation = L"";
int status_code = this->GetElementFindMethod(mechanism,
&mechanism_translation);
if (status_code != SUCCESS) {
LOG(WARN) << "Unable to determine mechanism translation for " << mechanism;
return status_code;
}
std::wstring wide_criteria = CA2W(criteria.c_str(), CP_UTF8);
return this->element_finder().FindElement(*this,
parent_wrapper,
mechanism_translation,
wide_criteria,
found_element);
}
int IECommandExecutor::LocateElements(const ElementHandle parent_wrapper,
const std::string& mechanism,
const std::string& criteria,
Json::Value* found_elements) const {
LOG(TRACE) << "Entering IECommandExecutor::LocateElements";
std::wstring mechanism_translation = L"";
int status_code = this->GetElementFindMethod(mechanism,
&mechanism_translation);
if (status_code != SUCCESS) {
LOG(WARN) << "Unable to determine mechanism translation for " << mechanism;
return status_code;
}
std::wstring wide_criteria = CA2W(criteria.c_str(), CP_UTF8);
return this->element_finder().FindElements(*this,
parent_wrapper,
mechanism_translation,
wide_criteria,
found_elements);
}
void IECommandExecutor::PopulateElementFinderMethods(void) {
LOG(TRACE) << "Entering IECommandExecutor::PopulateElementFinderMethods";
this->element_find_methods_["id"] = L"id";
this->element_find_methods_["name"] = L"name";
this->element_find_methods_["tag name"] = L"tagName";
this->element_find_methods_["link text"] = L"linkText";
this->element_find_methods_["partial link text"] = L"partialLinkText";
this->element_find_methods_["class name"] = L"className";
this->element_find_methods_["xpath"] = L"xpath";
this->element_find_methods_["css selector"] = L"css";
}
void IECommandExecutor::PopulateCommandHandlers() {
LOG(TRACE) << "Entering IECommandExecutor::PopulateCommandHandlers";
this->command_handlers_[webdriver::CommandType::NoCommand] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::GetCurrentWindowHandle] = CommandHandlerHandle(new GetCurrentWindowHandleCommandHandler);
this->command_handlers_[webdriver::CommandType::GetWindowHandles] = CommandHandlerHandle(new GetAllWindowHandlesCommandHandler);
this->command_handlers_[webdriver::CommandType::SwitchToWindow] = CommandHandlerHandle(new SwitchToWindowCommandHandler);
this->command_handlers_[webdriver::CommandType::SwitchToFrame] = CommandHandlerHandle(new SwitchToFrameCommandHandler);
this->command_handlers_[webdriver::CommandType::Get] = CommandHandlerHandle(new GoToUrlCommandHandler);
this->command_handlers_[webdriver::CommandType::GoForward] = CommandHandlerHandle(new GoForwardCommandHandler);
this->command_handlers_[webdriver::CommandType::GoBack] = CommandHandlerHandle(new GoBackCommandHandler);
this->command_handlers_[webdriver::CommandType::Refresh] = CommandHandlerHandle(new RefreshCommandHandler);
this->command_handlers_[webdriver::CommandType::ImplicitlyWait] = CommandHandlerHandle(new SetImplicitWaitTimeoutCommandHandler);
this->command_handlers_[webdriver::CommandType::SetAsyncScriptTimeout] = CommandHandlerHandle(new SetAsyncScriptTimeoutCommandHandler);
this->command_handlers_[webdriver::CommandType::SetTimeout] = CommandHandlerHandle(new SetTimeoutCommandHandler);
this->command_handlers_[webdriver::CommandType::NewSession] = CommandHandlerHandle(new NewSessionCommandHandler);
this->command_handlers_[webdriver::CommandType::GetSessionCapabilities] = CommandHandlerHandle(new GetSessionCapabilitiesCommandHandler);
this->command_handlers_[webdriver::CommandType::Close] = CommandHandlerHandle(new CloseWindowCommandHandler);
this->command_handlers_[webdriver::CommandType::Quit] = CommandHandlerHandle(new QuitCommandHandler);
this->command_handlers_[webdriver::CommandType::GetTitle] = CommandHandlerHandle(new GetTitleCommandHandler);
this->command_handlers_[webdriver::CommandType::GetPageSource] = CommandHandlerHandle(new GetPageSourceCommandHandler);
this->command_handlers_[webdriver::CommandType::GetCurrentUrl] = CommandHandlerHandle(new GetCurrentUrlCommandHandler);
this->command_handlers_[webdriver::CommandType::ExecuteAsyncScript] = CommandHandlerHandle(new ExecuteAsyncScriptCommandHandler);
this->command_handlers_[webdriver::CommandType::ExecuteScript] = CommandHandlerHandle(new ExecuteScriptCommandHandler);
this->command_handlers_[webdriver::CommandType::GetActiveElement] = CommandHandlerHandle(new GetActiveElementCommandHandler);
this->command_handlers_[webdriver::CommandType::FindElement] = CommandHandlerHandle(new FindElementCommandHandler);
this->command_handlers_[webdriver::CommandType::FindElements] = CommandHandlerHandle(new FindElementsCommandHandler);
this->command_handlers_[webdriver::CommandType::FindChildElement] = CommandHandlerHandle(new FindChildElementCommandHandler);
this->command_handlers_[webdriver::CommandType::FindChildElements] = CommandHandlerHandle(new FindChildElementsCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementTagName] = CommandHandlerHandle(new GetElementTagNameCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementLocation] = CommandHandlerHandle(new GetElementLocationCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementSize] = CommandHandlerHandle(new GetElementSizeCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementLocationOnceScrolledIntoView] = CommandHandlerHandle(new GetElementLocationOnceScrolledIntoViewCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementAttribute] = CommandHandlerHandle(new GetElementAttributeCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementText] = CommandHandlerHandle(new GetElementTextCommandHandler);
this->command_handlers_[webdriver::CommandType::GetElementValueOfCssProperty] = CommandHandlerHandle(new GetElementValueOfCssPropertyCommandHandler);
this->command_handlers_[webdriver::CommandType::ClickElement] = CommandHandlerHandle(new ClickElementCommandHandler);
this->command_handlers_[webdriver::CommandType::ClearElement] = CommandHandlerHandle(new ClearElementCommandHandler);
this->command_handlers_[webdriver::CommandType::SubmitElement] = CommandHandlerHandle(new SubmitElementCommandHandler);
this->command_handlers_[webdriver::CommandType::IsElementDisplayed] = CommandHandlerHandle(new IsElementDisplayedCommandHandler);
this->command_handlers_[webdriver::CommandType::IsElementSelected] = CommandHandlerHandle(new IsElementSelectedCommandHandler);
this->command_handlers_[webdriver::CommandType::IsElementEnabled] = CommandHandlerHandle(new IsElementEnabledCommandHandler);
this->command_handlers_[webdriver::CommandType::SendKeysToElement] = CommandHandlerHandle(new SendKeysCommandHandler);
this->command_handlers_[webdriver::CommandType::ElementEquals] = CommandHandlerHandle(new ElementEqualsCommandHandler);
this->command_handlers_[webdriver::CommandType::AddCookie] = CommandHandlerHandle(new AddCookieCommandHandler);
this->command_handlers_[webdriver::CommandType::GetAllCookies] = CommandHandlerHandle(new GetAllCookiesCommandHandler);
this->command_handlers_[webdriver::CommandType::DeleteCookie] = CommandHandlerHandle(new DeleteCookieCommandHandler);
this->command_handlers_[webdriver::CommandType::DeleteAllCookies] = CommandHandlerHandle(new DeleteAllCookiesCommandHandler);
this->command_handlers_[webdriver::CommandType::Screenshot] = CommandHandlerHandle(new ScreenshotCommandHandler);
this->command_handlers_[webdriver::CommandType::AcceptAlert] = CommandHandlerHandle(new AcceptAlertCommandHandler);
this->command_handlers_[webdriver::CommandType::DismissAlert] = CommandHandlerHandle(new DismissAlertCommandHandler);
this->command_handlers_[webdriver::CommandType::GetAlertText] = CommandHandlerHandle(new GetAlertTextCommandHandler);
this->command_handlers_[webdriver::CommandType::SendKeysToAlert] = CommandHandlerHandle(new SendKeysToAlertCommandHandler);
this->command_handlers_[webdriver::CommandType::MouseMoveTo] = CommandHandlerHandle(new MouseMoveToCommandHandler);
this->command_handlers_[webdriver::CommandType::MouseClick] = CommandHandlerHandle(new MouseClickCommandHandler);
this->command_handlers_[webdriver::CommandType::MouseDoubleClick] = CommandHandlerHandle(new MouseDoubleClickCommandHandler);
this->command_handlers_[webdriver::CommandType::MouseButtonDown] = CommandHandlerHandle(new MouseButtonDownCommandHandler);
this->command_handlers_[webdriver::CommandType::MouseButtonUp] = CommandHandlerHandle(new MouseButtonUpCommandHandler);
this->command_handlers_[webdriver::CommandType::SendKeysToActiveElement] = CommandHandlerHandle(new SendKeysToActiveElementCommandHandler);
this->command_handlers_[webdriver::CommandType::GetWindowSize] = CommandHandlerHandle(new GetWindowSizeCommandHandler);
this->command_handlers_[webdriver::CommandType::SetWindowSize] = CommandHandlerHandle(new SetWindowSizeCommandHandler);
this->command_handlers_[webdriver::CommandType::GetWindowPosition] = CommandHandlerHandle(new GetWindowPositionCommandHandler);
this->command_handlers_[webdriver::CommandType::SetWindowPosition] = CommandHandlerHandle(new SetWindowPositionCommandHandler);
this->command_handlers_[webdriver::CommandType::MaximizeWindow] = CommandHandlerHandle(new MaximizeWindowCommandHandler);
// As-yet unimplemented commands
this->command_handlers_[webdriver::CommandType::GetOrientation] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::SetOrientation] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::ListAvailableImeEngines] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::GetActiveImeEngine] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::IsImeActivated] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::ActivateImeEngine] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::DeactivateImeEngine] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchClick] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchDown] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchUp] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchMove] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchScroll] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchDoubleClick] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchLongClick] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::TouchFlick] = CommandHandlerHandle(new IECommandHandler);
// Commands intercepted by the server before reaching the command executor
this->command_handlers_[webdriver::CommandType::Status] = CommandHandlerHandle(new IECommandHandler);
this->command_handlers_[webdriver::CommandType::GetSessionList] = CommandHandlerHandle(new IECommandHandler);
}
} // namespace webdriver