Skip to content

Commit

Permalink
Refactoring of IE driver native events interaction code.
Browse files Browse the repository at this point in the history
This commit removes the dependency on shared native event code with
Firefox. Since Firefox no longer supports native events, it makes no
sense to have common code refactored for only one consumer, so this
commit moves the Windows-only SendMessage code directly into the IE
driver. This is a first step toward deleting the webdriver-interactions
directory. While extreme care has been taken to ensure this refactoring
causes no regressions, there is a chance something will still break.
This particular refactor should also be treated as an intermediate
step, as the ported code contains some redundancies to what is already
present in the driver. Future refactoring will take place to remove the
redundancies and better integrate the code.
  • Loading branch information
jimevans committed Dec 17, 2015
1 parent 24ff037 commit 5bcbb99
Show file tree
Hide file tree
Showing 25 changed files with 1,762 additions and 68 deletions.
12 changes: 1 addition & 11 deletions cpp/IEDriverServer.sln
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "civetweb", "..\third_party\cpp\civetweb\civetweb.vcxproj", "{231A8BED-6F2D-4688-A3BD-920310621BBF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "json-cpp", "..\third_party\cpp\json-cpp\json-cpp.vcxproj", "{320F3BBE-8223-4E7F-ABEE-18D3BD57B1FD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webdriver-interactions", "webdriver-interactions\webdriver-interactions.vcxproj", "{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webdriver-server", "webdriver-server\webdriver-server.vcxproj", "{35A23A16-EF17-4CC3-8854-785025A304F3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IEDriver", "iedriver\IEDriver.vcxproj", "{BB72383B-427F-4191-B692-E4345A30E33C}"
Expand Down Expand Up @@ -39,14 +37,6 @@ Global
{320F3BBE-8223-4E7F-ABEE-18D3BD57B1FD}.Release|Win32.Build.0 = Release|Win32
{320F3BBE-8223-4E7F-ABEE-18D3BD57B1FD}.Release|x64.ActiveCfg = Release|x64
{320F3BBE-8223-4E7F-ABEE-18D3BD57B1FD}.Release|x64.Build.0 = Release|x64
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Debug|Win32.ActiveCfg = Debug|Win32
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Debug|Win32.Build.0 = Debug|Win32
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Debug|x64.ActiveCfg = Debug|x64
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Debug|x64.Build.0 = Debug|x64
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Release|Win32.ActiveCfg = Release|Win32
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Release|Win32.Build.0 = Release|Win32
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Release|x64.ActiveCfg = Release|x64
{87FA39A1-958E-478A-8AB9-6D5E5AAA3886}.Release|x64.Build.0 = Release|x64
{35A23A16-EF17-4CC3-8854-785025A304F3}.Debug|Win32.ActiveCfg = Debug|Win32
{35A23A16-EF17-4CC3-8854-785025A304F3}.Debug|Win32.Build.0 = Debug|Win32
{35A23A16-EF17-4CC3-8854-785025A304F3}.Debug|x64.ActiveCfg = Debug|x64
Expand Down
12 changes: 6 additions & 6 deletions cpp/iedriver/CommandHandlers/SendKeysCommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "../Browser.h"
#include "../IECommandHandler.h"
#include "../IECommandExecutor.h"
#include "interactions.h"
#include "../WindowUtilities.h"
#include "logging.h"

const LPCTSTR fileDialogNames[] = {
Expand Down Expand Up @@ -233,10 +233,10 @@ class SendKeysCommandHandler : public IECommandHandler {
HWND edit_field_window_handle = NULL;
int max_wait = 10;
while (!edit_field_window_handle && --max_wait) {
wait(200);
WindowUtilities::Wait(200);
edit_field_window_handle = dialog_window_handle;
for (int i = 1; fileDialogNames[i]; ++i) {
edit_field_window_handle = getChildWindow(edit_field_window_handle,
edit_field_window_handle = WindowUtilities::GetChildWindow(edit_field_window_handle,
fileDialogNames[i]);
}
}
Expand All @@ -254,7 +254,7 @@ class SendKeysCommandHandler : public IECommandHandler {
WM_SETTEXT,
0,
reinterpret_cast<LPARAM>(filename));
wait(1000);
WindowUtilities::Wait(1000);
curr = ::SendMessage(edit_field_window_handle, WM_GETTEXTLENGTH, 0, 0);
}

Expand Down Expand Up @@ -293,7 +293,7 @@ class SendKeysCommandHandler : public IECommandHandler {
}
}

wait(200);
WindowUtilities::Wait(200);
} else if (triedToDismiss) {
// Probably just a slow close
LOG(DEBUG) << "Did not find OK button, but did previously. Assume dialog dismiss worked.";
Expand Down Expand Up @@ -364,7 +364,7 @@ class SendKeysCommandHandler : public IECommandHandler {
// Hard-coded 1 second timeout here. Possible TODO is make this adjustable.
clock_t max_wait = clock() + CLOCKS_PER_SEC;
for (int i = clock(); i < max_wait; i = clock()) {
wait(1);
WindowUtilities::Wait(1);
CComPtr<IHTMLElement> active_wait_element;
if (document->get_activeElement(&active_wait_element) == S_OK && active_wait_element != NULL) {
CComPtr<IHTMLElement2> active_wait_element2;
Expand Down
1 change: 0 additions & 1 deletion cpp/iedriver/Element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include <algorithm>
#include "Browser.h"
#include "Generated/atoms.h"
#include "interactions.h"
#include "json.h"
#include "logging.h"
#include "Script.h"
Expand Down
12 changes: 10 additions & 2 deletions cpp/iedriver/IECommandExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,14 @@ LRESULT IECommandExecutor::OnNewHtmlDialog(UINT uMsg,
return 0;
}

LRESULT IECommandExecutor::OnQuit(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
this->input_manager_->StopPersistentEvents();
return 0;
}

LRESULT IECommandExecutor::OnGetQuitStatus(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
Expand Down Expand Up @@ -665,11 +673,11 @@ int IECommandExecutor::CreateNewBrowser(std::string* error_message) {
return ENOSUCHDRIVER;
}
// Set persistent hover functionality in the interactions implementation.
setEnablePersistentHover(this->enable_persistent_hover_);
this->input_manager_->SetPersistentEvents(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();
this->input_manager_->StopPersistentEvents();
}

this->proxy_manager_->SetProxySettings(process_window_info.hwndBrowser);
Expand Down
2 changes: 2 additions & 0 deletions cpp/iedriver/IECommandExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class IECommandExecutor : public CWindowImpl<IECommandExecutor> {
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)
END_MSG_MAP()

LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
Expand All @@ -86,6 +87,7 @@ class IECommandExecutor : public CWindowImpl<IECommandExecutor> {
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);

std::string session_id(void) const { return this->session_id_; }

Expand Down
3 changes: 2 additions & 1 deletion cpp/iedriver/IEDriver.def
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ EXPORTS
KeyboardHookProc @1
MouseHookProc @2
SetProxyWndProc @3
CookieWndProc @4
CookieWndProc @4
GetMessageProc @5
9 changes: 4 additions & 5 deletions cpp/iedriver/IEDriver.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,6 @@
<ProjectReference Include="..\..\third_party\cpp\json-cpp\json-cpp.vcxproj">
<Project>{320f3bbe-8223-4e7f-abee-18d3bd57b1fd}</Project>
</ProjectReference>
<ProjectReference Include="..\webdriver-interactions\webdriver-interactions.vcxproj">
<Project>{87fa39a1-958e-478a-8ab9-6d5e5aaa3886}</Project>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\webdriver-server\webdriver-server.vcxproj">
<Project>{35a23a16-ef17-4cc3-8854-785025a304f3}</Project>
<Private>true</Private>
Expand Down Expand Up @@ -245,6 +240,7 @@
<ClCompile Include="IESession.cpp" />
<ClCompile Include="IEWebDriverManagerCommandExecutor.cpp" />
<ClCompile Include="InputManager.cpp" />
<ClCompile Include="InteractionsManager.cpp" />
<ClCompile Include="RegistryUtilities.cpp" />
<ClCompile Include="Script.cpp" />
<ClCompile Include="stdafx.cpp">
Expand All @@ -257,6 +253,7 @@
<ClCompile Include="VariantUtilities.cpp" />
<ClCompile Include="WebDriver.cpp" />
<ClCompile Include="ProxyManager.cpp" />
<ClCompile Include="WindowUtilities.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Alert.h" />
Expand Down Expand Up @@ -288,6 +285,7 @@
<ClInclude Include="IESession.h" />
<ClInclude Include="IEWebDriverManagerCommandExecutor.h" />
<ClInclude Include="InputManager.h" />
<ClInclude Include="InteractionsManager.h" />
<ClInclude Include="LocationInfo.h" />
<ClInclude Include="messages.h" />
<ClInclude Include="RegistryUtilities.h" />
Expand Down Expand Up @@ -353,6 +351,7 @@
<ClInclude Include="Generated\atoms.h" />
<ClInclude Include="Generated\sizzle.h" />
<ClInclude Include="ProxyManager.h" />
<ClInclude Include="WindowUtilities.h" />
</ItemGroup>
<ItemGroup>
<None Include="IEDriver.def" />
Expand Down
12 changes: 12 additions & 0 deletions cpp/iedriver/IEDriver.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@
<ClCompile Include="FileUtilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InteractionsManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WindowUtilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Browser.h">
Expand Down Expand Up @@ -385,6 +391,12 @@
<ClInclude Include="FileUtilities.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InteractionsManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WindowUtilities.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="IEDriver.def">
Expand Down
5 changes: 1 addition & 4 deletions cpp/iedriver/IESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "CommandExecutor.h"
#include "IECommandExecutor.h"
#include "IEWebDriverManagerCommandExecutor.h"
#include "interactions.h"
#include "logging.h"
#include "messages.h"

Expand Down Expand Up @@ -141,9 +140,7 @@ void IESession::ShutDown(void) {
LOG(TRACE) << "Entering IESession::ShutDown";

// Kill the background thread first - otherwise the IE process crashes.
if (this->driver_implementation_ == LegacyImplementation) {
stopPersistentEventFiring();
}
::SendMessage(this->executor_window_handle_, WD_QUIT, NULL, NULL);

// Don't terminate the thread until the browsers have all been deallocated.
// Note: Loop count of 6, because the timeout is 5 seconds, giving us a nice,
Expand Down
3 changes: 1 addition & 2 deletions cpp/iedriver/IEWebDriverManagerCommandExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "command_types.h"
#include "errorcodes.h"
#include "IEWebDriverManagerIds.h"
#include "interactions.h"
#include "json.h"
#include "logging.h"
#include "RegistryUtilities.h"
Expand Down Expand Up @@ -58,7 +57,7 @@ LRESULT IEWebDriverManagerCommandExecutor::OnCreate(UINT uMsg,
this->serialized_response_ = "";

// This call may not be required, but let's not take any chances.
setEnablePersistentHover(false);
//setEnablePersistentHover(false);
this->factory_ = new BrowserFactory();

HRESULT hr = ::CoCreateInstance(CLSID_IEWebDriverManager,
Expand Down
59 changes: 37 additions & 22 deletions cpp/iedriver/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "ElementRepository.h"
#include "HookProcessor.h"
#include "InputManager.h"
#include "interactions.h"
#include "InteractionsManager.h"
#include "json.h"
#include "keycodes.h"
#include "logging.h"
Expand All @@ -46,9 +46,14 @@ InputManager::InputManager() {
CComVariant mouse_state;
mouse_state.vt = VT_NULL;
this->mouse_state_ = mouse_state;

this->interactions_manager_ = new InteractionsManager();
}

InputManager::~InputManager(void) {
if (this->interactions_manager_ != NULL) {
delete this->interactions_manager_;
}
}

void InputManager::Initialize(ElementRepository* element_map) {
Expand Down Expand Up @@ -239,10 +244,10 @@ int InputManager::MouseClick(BrowserHandle browser_wrapper, int button) {
this->AddMouseInput(browser_window_handle, up_flag, this->last_known_mouse_x_, this->last_known_mouse_y_);
} else {
LOG(DEBUG) << "Using SendMessage method for mouse click";
clickAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
button);
this->interactions_manager_->clickAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
button);
}
} else {
LOG(DEBUG) << "Using synthetic events for mouse click";
Expand Down Expand Up @@ -298,10 +303,10 @@ int InputManager::MouseButtonDown(BrowserHandle browser_wrapper) {
} else {
LOG(DEBUG) << "Using SendMessage method for mouse button down";
//TODO: json wire protocol allows 3 mouse button types for this command
mouseDownAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
MOUSEBUTTON_LEFT);
this->interactions_manager_->mouseDownAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
MOUSEBUTTON_LEFT);
}
} else {
LOG(DEBUG) << "Using synthetic events for mouse button down";
Expand Down Expand Up @@ -335,10 +340,10 @@ int InputManager::MouseButtonUp(BrowserHandle browser_wrapper) {
} else {
LOG(DEBUG) << "Using SendMessage method for mouse button up";
//TODO: json wire protocol allows 3 mouse button types for this command
mouseUpAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
MOUSEBUTTON_LEFT);
this->interactions_manager_->mouseUpAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_,
MOUSEBUTTON_LEFT);
}
} else {
LOG(DEBUG) << "Using synthetic events for mouse button up";
Expand Down Expand Up @@ -374,7 +379,9 @@ int InputManager::MouseDoubleClick(BrowserHandle browser_wrapper) {
this->AddMouseInput(browser_window_handle, MOUSEEVENTF_LEFTUP, this->last_known_mouse_x_, this->last_known_mouse_y_);
} else {
LOG(DEBUG) << "Using SendMessage method for mouse double click";
doubleClickAt(browser_window_handle, this->last_known_mouse_x_, this->last_known_mouse_y_);
this->interactions_manager_->doubleClickAt(browser_window_handle,
this->last_known_mouse_x_,
this->last_known_mouse_y_);
}
} else {
LOG(DEBUG) << "Using synthetic events for mouse double click";
Expand Down Expand Up @@ -468,12 +475,12 @@ int InputManager::MouseMoveTo(BrowserHandle browser_wrapper, std::string element
}
} else {
LOG(DEBUG) << "Using SendMessage method for mouse move";
LRESULT move_result = mouseMoveTo(browser_window_handle,
10,
start_x,
start_y,
end_x,
end_y);
LRESULT move_result = this->interactions_manager_->mouseMoveTo(browser_window_handle,
10,
start_x,
start_y,
end_x,
end_y);
}
this->last_known_mouse_x_ = end_x;
this->last_known_mouse_y_ = end_y;
Expand Down Expand Up @@ -513,6 +520,14 @@ int InputManager::MouseMoveTo(BrowserHandle browser_wrapper, std::string element
return status_code;
}

void InputManager::SetPersistentEvents(bool is_firing) {
this->interactions_manager_->setEnablePersistentHover(is_firing);
}

void InputManager::StopPersistentEvents() {
this->interactions_manager_->stopPersistentEventFiring();
}

int InputManager::SendKeystrokes(BrowserHandle browser_wrapper, Json::Value keystroke_array, bool auto_release_modifier_keys) {
LOG(TRACE) << "Entering InputManager::SendKeystrokes";
int status_code = WD_SUCCESS;
Expand Down Expand Up @@ -542,9 +557,9 @@ int InputManager::SendKeystrokes(BrowserHandle browser_wrapper, Json::Value keys
}
} else {
LOG(DEBUG) << "Using SendMessage method for sending keys";
sendKeys(window_handle, keys.c_str(), 0);
this->interactions_manager_->sendKeys(window_handle, keys.c_str(), 0);
if (auto_release_modifier_keys) {
releaseModifierKeys(window_handle, 0);
this->interactions_manager_->releaseModifierKeys(window_handle, 0);
}
}
} else {
Expand Down
Loading

0 comments on commit 5bcbb99

Please sign in to comment.