| // Licensed to the Software Freedom Conservancy (SFC) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The SFC licenses this file |
| // to you 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. |
| |
| #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 { |
| |
| // Forward declaration of classes. |
| class BrowserFactory; |
| class CommandHandlerRepository; |
| class ElementFinder; |
| class ElementRepository; |
| class InputManager; |
| class ProxyManager; |
| |
| // We use a CWindowImpl (creating a hidden window) here because we |
| // want to synchronize access to the command handler. For that we |
| // use SendMessage() most of the time, and SendMessage() requires |
| // a window handle. |
| 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_; |
| }; |
| |
| } // namespace webdriver |
| |
| #endif // WEBDRIVER_IE_IECOMMANDEXECUTOR_H_ |