Skip to content

Commit 5c8380b

Browse files
committed
Rewriting IE driver file upload dialog handling code.
Previously, the IE driver would use simple window handling and Windows APIs to find and manipulate the IE file selection dialog for the file upload case. With this change, the driver now uses the Windows UI Automation library that ships as part of the Windows operating system to detect and manipulate the dialog. Unfortunately, since handling native dialogs this way is highly OS-dependent, there may be changes in behavior based on different versions of Windows, or different versions of IE. At the moment, this change has been tested against Windows 10, and IE 11. Other versions may not work exactly the same. Temporarily, to retain backward compatibility, it's possible to use the legacy handling with the file upload dialog box. This can be set by setting a capability of "ie.useLegacyFileUploadDialogHandling" to true. This capability is only intended to be provided temporarily, and will be removed as soon as is practical. As such, the capability is not documented, and its presence should not be relied on over the long term. It should be pointed out that, as has been the case since July 2016, the driver now only supports IE versions 9, 10, and 11, and only supports Windows Vista and above.
1 parent 4497162 commit 5c8380b

File tree

10 files changed

+953
-556
lines changed

10 files changed

+953
-556
lines changed

cpp/iedriver/CommandHandlers/NewSessionCommandHandler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ void NewSessionCommandHandler::SetInputSettings(const IECommandExecutor& executo
134134
mutable_executor.set_file_upload_dialog_timeout(file_upload_dialog_timeout.asInt());
135135
}
136136

137+
Json::Value use_legacy_file_upload_dialog_handling = this->GetCapability(capabilities, USE_LEGACY_FILE_UPLOAD_DIALOG_HANDLING_CAPABILITY, Json::booleanValue, false);
138+
mutable_executor.set_use_legacy_file_upload_dialog_handling(use_legacy_file_upload_dialog_handling.asBool());
139+
137140
Json::Value enable_persistent_hover = this->GetCapability(capabilities, ENABLE_PERSISTENT_HOVER_CAPABILITY, Json::booleanValue, true);
138141
if (require_window_focus.asBool() || !enable_native_events.asBool()) {
139142
// Setting "require_window_focus" implies SendInput() API, and does not therefore require
@@ -203,6 +206,7 @@ Json::Value NewSessionCommandHandler::CreateReturnedCapabilities(const IECommand
203206
ie_options[ELEMENT_SCROLL_BEHAVIOR_CAPABILITY] = executor.input_manager()->scroll_behavior();
204207
ie_options[REQUIRE_WINDOW_FOCUS_CAPABILITY] = executor.input_manager()->require_window_focus();
205208
ie_options[FILE_UPLOAD_DIALOG_TIMEOUT_CAPABILITY] = executor.file_upload_dialog_timeout();
209+
ie_options[USE_LEGACY_FILE_UPLOAD_DIALOG_HANDLING_CAPABILITY] = executor.use_legacy_file_upload_dialog_handling();
206210
ie_options[ENABLE_ELEMENT_CACHE_CLEANUP_CAPABILITY] = executor.enable_element_cache_cleanup();
207211
ie_options[ENABLE_FULL_PAGE_SCREENSHOT_CAPABILITY] = executor.enable_full_page_screenshot();
208212

cpp/iedriver/CommandHandlers/SendKeysCommandHandler.cpp

Lines changed: 368 additions & 22 deletions
Large diffs are not rendered by default.

cpp/iedriver/CommandHandlers/SendKeysCommandHandler.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020
#include "../IECommandHandler.h"
2121

22+
struct IUIAutomation;
23+
struct IUIAutomationElement;
24+
struct IUIAutomationElementArray;
25+
2226
namespace webdriver {
2327

2428
class SendKeysCommandHandler : public IECommandHandler {
@@ -28,6 +32,7 @@ class SendKeysCommandHandler : public IECommandHandler {
2832
HWND hwnd;
2933
DWORD ieProcId;
3034
DWORD dialogTimeout;
35+
bool useLegacyDialogHandling;
3136
const wchar_t* text;
3237
};
3338

@@ -40,13 +45,24 @@ class SendKeysCommandHandler : public IECommandHandler {
4045
Response* response);
4146
private:
4247
static unsigned int WINAPI SetFileValue(void *file_data);
43-
static bool SendKeysToFileUploadAlert(HWND dialog_window_handle,
44-
const wchar_t* value);
48+
static bool SendFileNameKeys(FileNameData* file_data);
49+
static bool GetFileSelectionDialogCandidates(HWND ie_window_handle, IUIAutomation* ui_automation, IUIAutomationElementArray** dialog_candidates);
50+
static bool FillFileName(const wchar_t* file_name, IUIAutomation* ui_automation, IUIAutomationElement* file_selection_dialog);
51+
static bool AcceptFileSelection(IUIAutomation* ui_automation, IUIAutomationElement* file_selection_dialog);
52+
static bool WaitForFileSelectionDialogClose(const int timeout, IUIAutomationElement* file_selection_dialog);
53+
static bool FindFileSelectionErrorDialog(IUIAutomation* ui_automation, IUIAutomationElement* file_selection_dialog, IUIAutomationElement** error_dialog);
54+
static bool DismissFileSelectionErrorDialog(IUIAutomation* ui_automation, IUIAutomationElement* error_dialog);
55+
static bool DismissFileSelectionDialog(IUIAutomation* ui_automation, IUIAutomationElement* file_selection_dialog);
56+
57+
static bool LegacySelectFile(FileNameData* file_data);
58+
static bool LegacySendKeysToFileUploadAlert(HWND dialog_window_handle, const wchar_t* value);
4559

4660
bool VerifyPageHasFocus(HWND top_level_window_handle,
4761
HWND browser_pane_window_handle);
4862
bool WaitUntilElementFocused(IHTMLElement *element);
4963
bool SetInsertionPoint(IHTMLElement* element);
64+
65+
static std::wstring error_text;
5066
};
5167

5268
} // namespace webdriver

cpp/iedriver/Generated/atoms.h

Lines changed: 532 additions & 532 deletions
Large diffs are not rendered by default.

cpp/iedriver/IECommandExecutor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ class IECommandExecutor : public CWindowImpl<IECommandExecutor> {
190190
this->file_upload_dialog_timeout_ = file_upload_dialog_timeout;
191191
}
192192

193+
bool use_legacy_file_upload_dialog_handling(void) const {
194+
return this->use_legacy_file_upload_dialog_handling_;
195+
}
196+
void set_use_legacy_file_upload_dialog_handling(const bool use_legacy_file_upload_dialog_handling) {
197+
this->use_legacy_file_upload_dialog_handling_ = use_legacy_file_upload_dialog_handling;
198+
}
199+
193200
bool enable_full_page_screenshot(void) const {
194201
return this->enable_full_page_screenshot_;
195202
}
@@ -246,6 +253,7 @@ class IECommandExecutor : public CWindowImpl<IECommandExecutor> {
246253
std::string unexpected_alert_behavior_;
247254
std::string page_load_strategy_;
248255
int file_upload_dialog_timeout_;
256+
bool use_legacy_file_upload_dialog_handling_;
249257
bool enable_full_page_screenshot_;
250258

251259
Command current_command_;

cpp/iedriver/IECommandHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#define ENSURE_CLEAN_SESSION_CAPABILITY "ie.ensureCleanSession"
5252
#define FORCE_SHELL_WINDOWS_API_CAPABILITY "ie.forceShellWindowsApi"
5353
#define FILE_UPLOAD_DIALOG_TIMEOUT_CAPABILITY "ie.fileUploadDialogTimeout"
54+
#define USE_LEGACY_FILE_UPLOAD_DIALOG_HANDLING_CAPABILITY "ie.useLegacyFileUploadDialogHandling"
5455
#define ENABLE_FULL_PAGE_SCREENSHOT_CAPABILITY "ie.enableFullPageScreenshot"
5556
#define IE_DRIVER_EXTENSIONS_CAPABILITY "se:ieOptions"
5657

cpp/iedriverserver/CHANGELOG

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@ available via the project downloads page. Changes in "revision" field indicate
99
private releases checked into the prebuilts directory of the source tree, but
1010
not made generally available on the downloads page.
1111

12+
v3.3.0.2
13+
========
14+
* Updates to JavaScript automation atoms.
15+
* Rewriting file upload dialog handling code. Previously, the IE driver
16+
would use simple window handling and Windows APIs to find and manipulate
17+
the IE file selection dialog for the file upload case. With this change,
18+
the driver now uses the Windows UI Automation library that ships as part
19+
of the Windows operating system to detect and manipulate the dialog.
20+
Unfortunately, since handling native dialogs this way is highly OS-
21+
dependent, there may be changes in behavior based on different versions
22+
of Windows, or different versions of IE. At the moment, this change
23+
has been tested against Windows 10, and IE 11. Other versions may not
24+
work exactly the same. Temporarily, to retain backward compatibility,
25+
it's possible to use the legacy handling with the file upload dialog
26+
box. This can be set by setting a capability of
27+
"ie.useLegacyFileUploadDialogHandling" to true. This capability is only
28+
intended to be provided temporarily, and will be removed as soon as is
29+
practical. As such, the capability is not documented, and its presence
30+
should not be relied on over the long term. It should be pointed out
31+
that, as has been the case since July 2016, the driver now only supports
32+
IE versions 9, 10, and 11, and only supports Windows Vista and above.
33+
1234
v3.3.0.1
1335
========
1436
* Updates to JavaScript automation atoms.
0 Bytes
Binary file not shown.
18.5 KB
Binary file not shown.
26 KB
Binary file not shown.

0 commit comments

Comments
 (0)