Skip to content

Commit

Permalink
Integrating the Microsoft Internet Explorer driver implementation
Browse files Browse the repository at this point in the history
This commit optionally allows the user to use the Microsoft-supplied
implementation of WebDriver for IE 11 and above. To use the Microsoft
implementation, the user must have the August 2014 updates to Internet
Explorer installed through Windows Update, and must install the IE Web
Driver Tool for Internet Explorer 11 download from Microsoft
(http://www.microsoft.com/en-us/download/details.aspx?id=44069).

Once those prerequisites are installed, the user can use the
InternetExplorerDriverService object in the language bindings to set the
implementation to be used.

By default, the driver will continue to use the driver implementation
developed by the open-source project. Over time as the Microsoft
implementation matures, this will be switched to use that implementation,
first by default, then exclusively.
  • Loading branch information
jimevans committed Sep 5, 2014
1 parent ea7cf41 commit 4437901
Show file tree
Hide file tree
Showing 43 changed files with 1,316 additions and 168 deletions.
29 changes: 29 additions & 0 deletions cpp/iedriver/CommandExecutor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2014 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.

#ifndef WEBDRIVER_IE_COMMANDEXECUTOR_H_
#define WEBDRIVER_IE_COMMANDEXECUTOR_H_

#define EVENT_NAME L"WD_START_EVENT"

namespace webdriver {

// Structure to be used for comunication between threads
struct IECommandExecutorThreadContext {
HWND hwnd;
int port;
};

} // namespace webdriver

#endif // WEBDRIVER_IE_COMMANDEXECUTOR_H_
1 change: 1 addition & 0 deletions cpp/iedriver/IECommandExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <algorithm>
#include <ctime>
#include <vector>
#include "CommandExecutor.h"
#include "logging.h"
#include "CommandHandlers/AcceptAlertCommandHandler.h"
#include "CommandHandlers/AddCookieCommandHandler.h"
Expand Down
8 changes: 0 additions & 8 deletions cpp/iedriver/IECommandExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,8 @@
#define ACCEPT_UNEXPECTED_ALERTS "accept"
#define DISMISS_UNEXPECTED_ALERTS "dismiss"

#define EVENT_NAME L"WD_START_EVENT"

namespace webdriver {

// Structure to be used for comunication between threads
struct IECommandExecutorThreadContext {
HWND hwnd;
int port;
};

// 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
Expand Down
11 changes: 7 additions & 4 deletions cpp/iedriver/IEDriver.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>Async</ExceptionHandling>
Expand Down Expand Up @@ -124,7 +124,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>Async</ExceptionHandling>
Expand Down Expand Up @@ -152,7 +152,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
Expand All @@ -179,7 +179,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
Expand Down Expand Up @@ -236,6 +236,7 @@
<ClCompile Include="IECommandHandler.cpp" />
<ClCompile Include="IEServer.cpp" />
<ClCompile Include="IESession.cpp" />
<ClCompile Include="IEWebDriverManagerCommandExecutor.cpp" />
<ClCompile Include="InputManager.cpp" />
<ClCompile Include="RegistryUtilities.cpp" />
<ClCompile Include="Script.cpp" />
Expand All @@ -255,6 +256,7 @@
<ClInclude Include="AsyncScriptExecutor.h" />
<ClInclude Include="Browser.h" />
<ClInclude Include="BrowserFactory.h" />
<ClInclude Include="CommandExecutor.h" />
<ClInclude Include="CommandHandlers\GetWindowPositionCommandHandler.h" />
<ClInclude Include="CommandHandlers\GetWindowSizeCommandHandler.h" />
<ClInclude Include="CommandHandlers\MaximizeWindowCommandHandler.h" />
Expand All @@ -272,6 +274,7 @@
<ClInclude Include="IECommandHandler.h" />
<ClInclude Include="IEServer.h" />
<ClInclude Include="IESession.h" />
<ClInclude Include="IEWebDriverManagerCommandExecutor.h" />
<ClInclude Include="InputManager.h" />
<ClInclude Include="LocationInfo.h" />
<ClInclude Include="messages.h" />
Expand Down
9 changes: 9 additions & 0 deletions cpp/iedriver/IEDriver.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@
<ClCompile Include="ProxyManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IEWebDriverManagerCommandExecutor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Browser.h">
Expand Down Expand Up @@ -352,6 +355,12 @@
<ClInclude Include="CommandHandlers\SwitchToParentFrameCommandHandler.h">
<Filter>Header Files\CommandHandlers</Filter>
</ClInclude>
<ClInclude Include="IEWebDriverManagerCommandExecutor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CommandExecutor.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="IEDriver.def">
Expand Down
5 changes: 4 additions & 1 deletion cpp/iedriver/IEServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ IEServer::IEServer(int port,
const std::string& host,
const std::string& log_level,
const std::string& log_file,
const std::string& version) : Server(port, host, log_level, log_file) {
const std::string& version,
const std::string& driver_implementation) : Server(port, host, log_level, log_file) {
LOG(TRACE) << "Entering IEServer::IEServer";

this->version_ = version;
this->driver_implementation_ = driver_implementation;
}

IEServer::~IEServer(void) {
Expand All @@ -35,6 +37,7 @@ SessionHandle IEServer::InitializeSession() {
SessionHandle session_handle(new IESession());
SessionParameters params;
params.port = this->port();
params.implementation = IESession::ConvertDriverEngine(this->driver_implementation_);
session_handle->Initialize(reinterpret_cast<void*>(&params));
return session_handle;
}
Expand Down
4 changes: 3 additions & 1 deletion cpp/iedriver/IEServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class IEServer : public Server {
const std::string& host,
const std::string& log_level,
const std::string& log_file,
const std::string& version);
const std::string& version,
const std::string& driver_implementation);
virtual ~IEServer(void);

protected:
Expand All @@ -35,6 +36,7 @@ class IEServer : public Server {
virtual void ShutDown(void);
private:
std::string version_;
std::string driver_implementation_;
};

} // namespace webdriver
Expand Down
37 changes: 26 additions & 11 deletions cpp/iedriver/IESession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
// limitations under the License.

#include "IESession.h"
#include "CommandExecutor.h"
#include "IECommandExecutor.h"
#include "logging.h"
#include "IEWebDriverManagerCommandExecutor.h"
#include "interactions.h"
#include "logging.h"
#include "messages.h"

typedef unsigned (__stdcall *ThreadProcedure)(void*);

namespace webdriver {

Expand Down Expand Up @@ -51,6 +56,7 @@ void IESession::Initialize(void* init_params) {

SessionParameters* params = reinterpret_cast<SessionParameters*>(init_params);
int port = params->port;
this->driver_implementation_ = params->implementation;

IECommandExecutorThreadContext thread_context;
thread_context.port = port;
Expand All @@ -62,9 +68,14 @@ void IESession::Initialize(void* init_params) {
if (event_handle == NULL) {
LOGERR(DEBUG) << "Unable to create event " << EVENT_NAME;
}

ThreadProcedure thread_proc = &IECommandExecutor::ThreadProc;
if (this->driver_implementation_ != LegacyImplementation) {
thread_proc = &IEWebDriverManagerCommandExecutor::ThreadProc;
}
HANDLE thread_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL,
0,
&IECommandExecutor::ThreadProc,
thread_proc,
reinterpret_cast<void*>(&thread_context),
0,
&thread_id));
Expand All @@ -85,14 +96,6 @@ void IESession::Initialize(void* init_params) {
std::string session_id = "";
if (thread_context.hwnd != NULL) {
LOG(TRACE) << "Created thread for command executor returns HWND: '" << thread_context.hwnd << "'";

// Send INIT to window with port as WPARAM
// It is already deprecated
::SendMessage(thread_context.hwnd,
WD_INIT,
static_cast<WPARAM>(port),
NULL);

std::vector<wchar_t> window_text_buffer(37);
::GetWindowText(thread_context.hwnd, &window_text_buffer[0], 37);
session_id = StringUtilities::ToString(&window_text_buffer[0]);
Expand All @@ -115,7 +118,9 @@ void IESession::ShutDown(void) {
LOG(TRACE) << "Entering IESession::ShutDown";

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

// 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 Expand Up @@ -230,4 +235,14 @@ bool IESession::ExecuteCommand(const std::string& serialized_command,
return session_is_valid;
}

DriverImplementation IESession::ConvertDriverEngine(const std::string& engine) {
if (engine == "VENDOR") {
return VendorImplementation;
}
if (engine == "AUTODETECT") {
return AutoDetectImplementation;
}
return LegacyImplementation;
}

} // namespace webdriver
10 changes: 10 additions & 0 deletions cpp/iedriver/IESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,33 @@

namespace webdriver {

enum DriverImplementation {
LegacyImplementation = 0,
AutoDetectImplementation,
VendorImplementation
};

// Structure to be used for storing session initialization parameters
struct SessionParameters {
int port;
DriverImplementation implementation;
};

class IESession : public Session {
public:
IESession();
virtual ~IESession(void);

static DriverImplementation ConvertDriverEngine(const std::string& engine);

void Initialize(void* init_params);
void ShutDown(void);
bool ExecuteCommand(const std::string& serialized_command,
std::string* serialized_response);

private:
bool WaitForCommandExecutorExit(int timeout_in_milliseconds);
DriverImplementation driver_implementation_;
HWND executor_window_handle_;
};

Expand Down
Loading

0 comments on commit 4437901

Please sign in to comment.