Skip to content

Commit 4437901

Browse files
committed
Integrating the Microsoft Internet Explorer driver implementation
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.
1 parent ea7cf41 commit 4437901

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1316
-168
lines changed

cpp/iedriver/CommandExecutor.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2014 Software Freedom Conservancy
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
#ifndef WEBDRIVER_IE_COMMANDEXECUTOR_H_
15+
#define WEBDRIVER_IE_COMMANDEXECUTOR_H_
16+
17+
#define EVENT_NAME L"WD_START_EVENT"
18+
19+
namespace webdriver {
20+
21+
// Structure to be used for comunication between threads
22+
struct IECommandExecutorThreadContext {
23+
HWND hwnd;
24+
int port;
25+
};
26+
27+
} // namespace webdriver
28+
29+
#endif // WEBDRIVER_IE_COMMANDEXECUTOR_H_

cpp/iedriver/IECommandExecutor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <algorithm>
1616
#include <ctime>
1717
#include <vector>
18+
#include "CommandExecutor.h"
1819
#include "logging.h"
1920
#include "CommandHandlers/AcceptAlertCommandHandler.h"
2021
#include "CommandHandlers/AddCookieCommandHandler.h"

cpp/iedriver/IECommandExecutor.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,8 @@
3939
#define ACCEPT_UNEXPECTED_ALERTS "accept"
4040
#define DISMISS_UNEXPECTED_ALERTS "dismiss"
4141

42-
#define EVENT_NAME L"WD_START_EVENT"
43-
4442
namespace webdriver {
4543

46-
// Structure to be used for comunication between threads
47-
struct IECommandExecutorThreadContext {
48-
HWND hwnd;
49-
int port;
50-
};
51-
5244
// We use a CWindowImpl (creating a hidden window) here because we
5345
// want to synchronize access to the command handler. For that we
5446
// use SendMessage() most of the time, and SendMessage() requires

cpp/iedriver/IEDriver.vcxproj

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
9393
<ClCompile>
9494
<Optimization>Disabled</Optimization>
95-
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
95+
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
9696
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
9797
<MinimalRebuild>false</MinimalRebuild>
9898
<ExceptionHandling>Async</ExceptionHandling>
@@ -124,7 +124,7 @@
124124
</Midl>
125125
<ClCompile>
126126
<Optimization>Disabled</Optimization>
127-
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
127+
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
128128
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
129129
<MinimalRebuild>false</MinimalRebuild>
130130
<ExceptionHandling>Async</ExceptionHandling>
@@ -152,7 +152,7 @@
152152
<ClCompile>
153153
<Optimization>MaxSpeed</Optimization>
154154
<IntrinsicFunctions>false</IntrinsicFunctions>
155-
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
155+
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
156156
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
157157
<ExceptionHandling>Async</ExceptionHandling>
158158
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -179,7 +179,7 @@
179179
<ClCompile>
180180
<Optimization>MaxSpeed</Optimization>
181181
<IntrinsicFunctions>false</IntrinsicFunctions>
182-
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
182+
<AdditionalIncludeDirectories>$(ProjectDir)..\webdriver-server;$(ProjectDir)..\webdriver-interactions;$(ProjectDir)..\..\third_party\json-cpp\include\json;$(ProjectDir)..\..\third_party\iewebdriverheader;$(ProjectDir)..\..\third_party\civetweb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
183183
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IEDRIVER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
184184
<ExceptionHandling>Async</ExceptionHandling>
185185
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -236,6 +236,7 @@
236236
<ClCompile Include="IECommandHandler.cpp" />
237237
<ClCompile Include="IEServer.cpp" />
238238
<ClCompile Include="IESession.cpp" />
239+
<ClCompile Include="IEWebDriverManagerCommandExecutor.cpp" />
239240
<ClCompile Include="InputManager.cpp" />
240241
<ClCompile Include="RegistryUtilities.cpp" />
241242
<ClCompile Include="Script.cpp" />
@@ -255,6 +256,7 @@
255256
<ClInclude Include="AsyncScriptExecutor.h" />
256257
<ClInclude Include="Browser.h" />
257258
<ClInclude Include="BrowserFactory.h" />
259+
<ClInclude Include="CommandExecutor.h" />
258260
<ClInclude Include="CommandHandlers\GetWindowPositionCommandHandler.h" />
259261
<ClInclude Include="CommandHandlers\GetWindowSizeCommandHandler.h" />
260262
<ClInclude Include="CommandHandlers\MaximizeWindowCommandHandler.h" />
@@ -272,6 +274,7 @@
272274
<ClInclude Include="IECommandHandler.h" />
273275
<ClInclude Include="IEServer.h" />
274276
<ClInclude Include="IESession.h" />
277+
<ClInclude Include="IEWebDriverManagerCommandExecutor.h" />
275278
<ClInclude Include="InputManager.h" />
276279
<ClInclude Include="LocationInfo.h" />
277280
<ClInclude Include="messages.h" />

cpp/iedriver/IEDriver.vcxproj.filters

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
<ClCompile Include="ProxyManager.cpp">
8787
<Filter>Source Files</Filter>
8888
</ClCompile>
89+
<ClCompile Include="IEWebDriverManagerCommandExecutor.cpp">
90+
<Filter>Source Files</Filter>
91+
</ClCompile>
8992
</ItemGroup>
9093
<ItemGroup>
9194
<ClInclude Include="Browser.h">
@@ -352,6 +355,12 @@
352355
<ClInclude Include="CommandHandlers\SwitchToParentFrameCommandHandler.h">
353356
<Filter>Header Files\CommandHandlers</Filter>
354357
</ClInclude>
358+
<ClInclude Include="IEWebDriverManagerCommandExecutor.h">
359+
<Filter>Header Files</Filter>
360+
</ClInclude>
361+
<ClInclude Include="CommandExecutor.h">
362+
<Filter>Header Files</Filter>
363+
</ClInclude>
355364
</ItemGroup>
356365
<ItemGroup>
357366
<None Include="IEDriver.def">

cpp/iedriver/IEServer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ IEServer::IEServer(int port,
2121
const std::string& host,
2222
const std::string& log_level,
2323
const std::string& log_file,
24-
const std::string& version) : Server(port, host, log_level, log_file) {
24+
const std::string& version,
25+
const std::string& driver_implementation) : Server(port, host, log_level, log_file) {
2526
LOG(TRACE) << "Entering IEServer::IEServer";
2627

2728
this->version_ = version;
29+
this->driver_implementation_ = driver_implementation;
2830
}
2931

3032
IEServer::~IEServer(void) {
@@ -35,6 +37,7 @@ SessionHandle IEServer::InitializeSession() {
3537
SessionHandle session_handle(new IESession());
3638
SessionParameters params;
3739
params.port = this->port();
40+
params.implementation = IESession::ConvertDriverEngine(this->driver_implementation_);
3841
session_handle->Initialize(reinterpret_cast<void*>(&params));
3942
return session_handle;
4043
}

cpp/iedriver/IEServer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class IEServer : public Server {
2626
const std::string& host,
2727
const std::string& log_level,
2828
const std::string& log_file,
29-
const std::string& version);
29+
const std::string& version,
30+
const std::string& driver_implementation);
3031
virtual ~IEServer(void);
3132

3233
protected:
@@ -35,6 +36,7 @@ class IEServer : public Server {
3536
virtual void ShutDown(void);
3637
private:
3738
std::string version_;
39+
std::string driver_implementation_;
3840
};
3941

4042
} // namespace webdriver

cpp/iedriver/IESession.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@
1212
// limitations under the License.
1313

1414
#include "IESession.h"
15+
#include "CommandExecutor.h"
1516
#include "IECommandExecutor.h"
16-
#include "logging.h"
17+
#include "IEWebDriverManagerCommandExecutor.h"
1718
#include "interactions.h"
19+
#include "logging.h"
20+
#include "messages.h"
21+
22+
typedef unsigned (__stdcall *ThreadProcedure)(void*);
1823

1924
namespace webdriver {
2025

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

5257
SessionParameters* params = reinterpret_cast<SessionParameters*>(init_params);
5358
int port = params->port;
59+
this->driver_implementation_ = params->implementation;
5460

5561
IECommandExecutorThreadContext thread_context;
5662
thread_context.port = port;
@@ -62,9 +68,14 @@ void IESession::Initialize(void* init_params) {
6268
if (event_handle == NULL) {
6369
LOGERR(DEBUG) << "Unable to create event " << EVENT_NAME;
6470
}
71+
72+
ThreadProcedure thread_proc = &IECommandExecutor::ThreadProc;
73+
if (this->driver_implementation_ != LegacyImplementation) {
74+
thread_proc = &IEWebDriverManagerCommandExecutor::ThreadProc;
75+
}
6576
HANDLE thread_handle = reinterpret_cast<HANDLE>(_beginthreadex(NULL,
6677
0,
67-
&IECommandExecutor::ThreadProc,
78+
thread_proc,
6879
reinterpret_cast<void*>(&thread_context),
6980
0,
7081
&thread_id));
@@ -85,14 +96,6 @@ void IESession::Initialize(void* init_params) {
8596
std::string session_id = "";
8697
if (thread_context.hwnd != NULL) {
8798
LOG(TRACE) << "Created thread for command executor returns HWND: '" << thread_context.hwnd << "'";
88-
89-
// Send INIT to window with port as WPARAM
90-
// It is already deprecated
91-
::SendMessage(thread_context.hwnd,
92-
WD_INIT,
93-
static_cast<WPARAM>(port),
94-
NULL);
95-
9699
std::vector<wchar_t> window_text_buffer(37);
97100
::GetWindowText(thread_context.hwnd, &window_text_buffer[0], 37);
98101
session_id = StringUtilities::ToString(&window_text_buffer[0]);
@@ -115,7 +118,9 @@ void IESession::ShutDown(void) {
115118
LOG(TRACE) << "Entering IESession::ShutDown";
116119

117120
// Kill the background thread first - otherwise the IE process crashes.
118-
stopPersistentEventFiring();
121+
if (this->driver_implementation_ == LegacyImplementation) {
122+
stopPersistentEventFiring();
123+
}
119124

120125
// Don't terminate the thread until the browsers have all been deallocated.
121126
// Note: Loop count of 6, because the timeout is 5 seconds, giving us a nice,
@@ -230,4 +235,14 @@ bool IESession::ExecuteCommand(const std::string& serialized_command,
230235
return session_is_valid;
231236
}
232237

238+
DriverImplementation IESession::ConvertDriverEngine(const std::string& engine) {
239+
if (engine == "VENDOR") {
240+
return VendorImplementation;
241+
}
242+
if (engine == "AUTODETECT") {
243+
return AutoDetectImplementation;
244+
}
245+
return LegacyImplementation;
246+
}
247+
233248
} // namespace webdriver

cpp/iedriver/IESession.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,33 @@
2424

2525
namespace webdriver {
2626

27+
enum DriverImplementation {
28+
LegacyImplementation = 0,
29+
AutoDetectImplementation,
30+
VendorImplementation
31+
};
32+
2733
// Structure to be used for storing session initialization parameters
2834
struct SessionParameters {
2935
int port;
36+
DriverImplementation implementation;
3037
};
3138

3239
class IESession : public Session {
3340
public:
3441
IESession();
3542
virtual ~IESession(void);
3643

44+
static DriverImplementation ConvertDriverEngine(const std::string& engine);
45+
3746
void Initialize(void* init_params);
3847
void ShutDown(void);
3948
bool ExecuteCommand(const std::string& serialized_command,
4049
std::string* serialized_response);
4150

4251
private:
4352
bool WaitForCommandExecutorExit(int timeout_in_milliseconds);
53+
DriverImplementation driver_implementation_;
4454
HWND executor_window_handle_;
4555
};
4656

0 commit comments

Comments
 (0)