#ifndef WEBDRIVER_IE_IECOMMANDEXECUTOR_H_
#define WEBDRIVER_IE_IECOMMANDEXECUTOR_H_
#include <ctime>
#include <map>
#include <mutex>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include "command.h"
#include "CustomTypes.h"
#include "IElementManager.h"
#include "messages.h"
namespace webdriver {
class BrowserFactory;
class CommandHandlerRepository;
class ElementFinder;
class ElementRepository;
class InputManager;
class ProxyManager;
class IECommandExecutor : public CWindowImpl<IECommandExecutor>, public IElementManager {
public:
DECLARE_WND_CLASS(L"WebDriverWndClass")
BEGIN_MSG_MAP(Session)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WD_SET_COMMAND, OnSetCommand)
MESSAGE_HANDLER(WD_EXEC_COMMAND, OnExecCommand)
MESSAGE_HANDLER(WD_GET_RESPONSE_LENGTH, OnGetResponseLength)
MESSAGE_HANDLER(WD_GET_RESPONSE, OnGetResponse)
MESSAGE_HANDLER(WD_WAIT, OnWait)
MESSAGE_HANDLER(WD_BROWSER_NEW_WINDOW, OnBrowserNewWindow)
MESSAGE_HANDLER(WD_BEFORE_NEW_WINDOW, OnBeforeNewWindow)
MESSAGE_HANDLER(WD_AFTER_NEW_WINDOW, OnAfterNewWindow)
MESSAGE_HANDLER(WD_BROWSER_QUIT, OnBrowserQuit)
MESSAGE_HANDLER(WD_BROWSER_CLOSE_WAIT, OnBrowserCloseWait)
MESSAGE_HANDLER(WD_BEFORE_BROWSER_REATTACH, OnBeforeBrowserReattach)
MESSAGE_HANDLER(WD_BROWSER_REATTACH, OnBrowserReattach)
MESSAGE_HANDLER(WD_IS_SESSION_VALID, OnIsSessionValid)
MESSAGE_HANDLER(WD_NEW_HTML_DIALOG, OnNewHtmlDialog)
MESSAGE_HANDLER(WD_GET_QUIT_STATUS, OnGetQuitStatus)
MESSAGE_HANDLER(WD_REFRESH_MANAGED_ELEMENTS, OnRefreshManagedElements)
MESSAGE_HANDLER(WD_HANDLE_UNEXPECTED_ALERTS, OnHandleUnexpectedAlerts)
MESSAGE_HANDLER(WD_QUIT, OnQuit)
MESSAGE_HANDLER(WD_SCRIPT_WAIT, OnScriptWait)
MESSAGE_HANDLER(WD_ASYNC_SCRIPT_TRANSFER_MANAGED_ELEMENT, OnTransferManagedElement)
MESSAGE_HANDLER(WD_ASYNC_SCRIPT_SCHEDULE_REMOVE_MANAGED_ELEMENT, OnScheduleRemoveManagedElement)
MESSAGE_HANDLER(WD_ADD_CHROMIUM_WINDOW_HANDLE, OnAddChromiumWindowHandle)
MESSAGE_HANDLER(WD_SESSION_QUIT_WAIT, OnSessionQuitWait)
END_MSG_MAP()
LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnExecCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetResponseLength(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetResponse(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnWait(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBrowserNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBeforeNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnAfterNewWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBrowserQuit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBrowserCloseWait(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBeforeBrowserReattach(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnBrowserReattach(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnIsSessionValid(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnNewHtmlDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnGetQuitStatus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRefreshManagedElements(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnHandleUnexpectedAlerts(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnQuit(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnScriptWait(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnTransferManagedElement(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnScheduleRemoveManagedElement(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnAddChromiumWindowHandle(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSessionQuitWait(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
std::string session_id(void) const { return this->session_id_; }
static unsigned int WINAPI ThreadProc(LPVOID lpParameter);
static unsigned int WINAPI WaitThreadProc(LPVOID lpParameter);
static unsigned int WINAPI ScriptWaitThreadProc(LPVOID lpParameter);
static unsigned int WINAPI DelayPostMessageThreadProc(LPVOID lpParameter);
std::string current_browser_id(void) const {
return this->current_browser_id_;
}
void set_current_browser_id(const std::string& browser_id) {
this->current_browser_id_ = browser_id;
}
int CreateNewBrowser(std::string* error_message);
std::string OpenNewBrowsingContext(const std::string& window_type);
int GetManagedBrowser(const std::string& browser_id,
BrowserHandle* browser_wrapper) const;
int GetCurrentBrowser(BrowserHandle* browser_wrapper) const;
void GetManagedBrowserHandles(
std::vector<std::string> *managed_browser_handles) const;
int GetManagedElement(const std::string& element_id,
ElementHandle* element_wrapper) const;
bool AddManagedElement(IHTMLElement* element,
ElementHandle* element_wrapper);
void RemoveManagedElement(const std::string& element_id);
void ListManagedElements(void);
int GetElementFindMethod(const std::string& mechanism,
std::wstring* translation) const;
int LocateElement(const ElementHandle parent_wrapper,
const std::string& mechanism,
const std::string& criteria,
Json::Value* found_element) const;
int LocateElements(const ElementHandle parent_wrapper,
const std::string& mechanism,
const std::string& criteria,
Json::Value* found_elements) const;
HWND window_handle(void) const { return this->m_hWnd; }
IElementManager* element_manager(void) { return this; }
unsigned long long implicit_wait_timeout(void) const {
return this->implicit_wait_timeout_;
}
void set_implicit_wait_timeout(const unsigned long long timeout) {
this->implicit_wait_timeout_ = timeout;
}
long long async_script_timeout(void) const { return this->async_script_timeout_; }
void set_async_script_timeout(const long long timeout) {
this->async_script_timeout_ = timeout;
}
unsigned long long page_load_timeout(void) const { return this->page_load_timeout_; }
void set_page_load_timeout(const unsigned long long timeout) {
this->page_load_timeout_ = timeout;
}
bool is_valid(void) const { return this->is_valid_; }
void set_is_valid(const bool session_is_valid) {
this->is_valid_ = session_is_valid;
}
bool is_quitting(void) const { return this->is_quitting_; }
void set_is_quitting(const bool session_is_quitting) {
this->is_quitting_ = session_is_quitting;
}
std::string unexpected_alert_behavior(void) const {
return this->unexpected_alert_behavior_;
}
void set_unexpected_alert_behavior(const std::string& unexpected_alert_behavior) {
this->unexpected_alert_behavior_ = unexpected_alert_behavior;
}
std::string page_load_strategy(void) const {
return this->page_load_strategy_;
}
void set_page_load_strategy(const std::string& page_load_strategy) {
this->page_load_strategy_ = page_load_strategy;
}
bool use_legacy_file_upload_dialog_handling(void) const {
return this->use_legacy_file_upload_dialog_handling_;
}
void set_use_legacy_file_upload_dialog_handling(const bool use_legacy_dialog_handling) {
this->use_legacy_file_upload_dialog_handling_ = use_legacy_dialog_handling;
}
int file_upload_dialog_timeout(void) const {
return this->file_upload_dialog_timeout_;
}
void set_file_upload_dialog_timeout(const int file_upload_dialog_timeout) {
this->file_upload_dialog_timeout_ = file_upload_dialog_timeout;
}
bool is_edge_mode(void) const {
return this->is_edge_chromium_;
}
void set_is_edge_mode(bool value) {
this->is_edge_chromium_ = value;
}
std::string edge_executable_path(void) const {
return this->edge_executable_path_;
}
void set_edge_executable_path(std::string path) {
this->edge_executable_path_ = path;
}
bool use_strict_file_interactability(void) const {
return this->use_strict_file_interactability_;
}
void set_use_strict_file_interactability(const bool use_strict_file_interactability) {
this->use_strict_file_interactability_ = use_strict_file_interactability;
}
ElementFinder* element_finder(void) const { return this->element_finder_; }
InputManager* input_manager(void) const { return this->input_manager_; }
ProxyManager* proxy_manager(void) const { return this->proxy_manager_; }
BrowserFactory* browser_factory(void) const { return this->factory_; }
int port(void) const { return this->port_; }
size_t managed_window_count(void) const {
return this->managed_browsers_.size();
}
private:
typedef std::unordered_map<std::string, BrowserHandle> BrowserMap;
typedef std::map<std::string, std::wstring> ElementFindMethodMap;
void AddManagedBrowser(BrowserHandle browser_wrapper);
void DispatchCommand(void);
void PopulateElementFinderMethods(void);
void CreateWaitThread(const std::string& deferred_response);
void CreateWaitThread(const std::string& deferred_response,
const bool is_deferred_command_execution);
void CreateDelayPostMessageThread(const DWORD delay_time,
const HWND window_handle,
const UINT message_to_post);
bool IsCommandValidWithAlertPresent(void);
bool IsAlertActive(BrowserHandle browser, HWND* alert_handle);
bool HandleUnexpectedAlert(BrowserHandle browser,
HWND alert_handle,
bool force_use_dismiss,
std::string* alert_text);
void PostBrowserReattachMessage(const DWORD current_process_id,
const std::string& browser_id,
const std::vector<DWORD>& known_process_ids);
void GetNewBrowserProcessIds(std::vector<DWORD>* known_process_ids,
std::vector<DWORD>* new_process_ids);
std::string OpenNewBrowsingContext(const std::string& window_type,
const std::string& url);
std::string OpenNewBrowserWindow(const std::wstring& url);
std::string OpenNewBrowserTab(const std::wstring& url);
BrowserMap managed_browsers_;
ElementRepository* managed_elements_;
ElementFindMethodMap element_find_methods_;
CommandHandlerRepository* command_handlers_;
std::string current_browser_id_;
ElementFinder* element_finder_;
unsigned long long implicit_wait_timeout_;
unsigned long long async_script_timeout_;
unsigned long long page_load_timeout_;
unsigned long long reattach_browser_timeout_;
clock_t wait_timeout_;
clock_t reattach_wait_timeout_;
std::string session_id_;
int port_;
bool ignore_zoom_setting_;
std::string initial_browser_url_;
std::string unexpected_alert_behavior_;
std::string page_load_strategy_;
int file_upload_dialog_timeout_;
bool use_legacy_file_upload_dialog_handling_;
bool enable_full_page_screenshot_;
bool use_strict_file_interactability_;
bool is_edge_chromium_;
std::string edge_executable_path_;
std::wstring edge_temp_dir_;
std::unordered_set<HWND> chromium_window_handles_;
Command current_command_;
std::string serialized_response_;
bool is_waiting_;
bool is_valid_;
bool is_quitting_;
bool is_awaiting_new_window_;
std::mutex set_command_mutex_;
BrowserFactory* factory_;
InputManager* input_manager_;
ProxyManager* proxy_manager_;
};
}
#endif