Skip to content

Commit

Permalink
Completing IE implementation of strictFileInteractability capability
Browse files Browse the repository at this point in the history
By default, the IE driver can interact with hidden <input type='file'>
elements. By setting this capability to false, it forces the driver
to make sure the file upload element is interactable like other
elements.
  • Loading branch information
jimevans committed Nov 19, 2018
1 parent 9c722fa commit 47f4439
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 22 deletions.
6 changes: 3 additions & 3 deletions cpp/iedriver/CommandHandlers/NewSessionCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ Json::Value NewSessionCommandHandler::ProcessCapabilities(const IECommandExecuto
Json::Value page_load_strategy = this->GetCapability(merged_capabilities, PAGE_LOAD_STRATEGY_CAPABILITY, Json::stringValue, NORMAL_PAGE_LOAD_STRATEGY);
mutable_executor.set_page_load_strategy(this->GetPageLoadStrategyValue(page_load_strategy.asString()));

Json::Value use_strict_file_interactability = this->GetCapability(merged_capabilities, STRICT_FILE_INTERACTABILITY_CAPABILITY, Json::booleanValue, false);
mutable_executor.set_use_strict_file_interactability(use_strict_file_interactability.asBool());

Json::Value timeouts = this->GetCapability(merged_capabilities, TIMEOUTS_CAPABILITY, Json::objectValue, Json::Value());
this->SetTimeoutSettings(executor, timeouts);

Expand Down Expand Up @@ -455,9 +458,6 @@ void NewSessionCommandHandler::SetInputSettings(const IECommandExecutor& executo
mutable_executor.set_file_upload_dialog_timeout(file_upload_dialog_timeout.asInt());
}

Json::Value use_strict_file_interactability = this->GetCapability(capabilities, STRICT_FILE_INTERACTABILITY_CAPABILITY, Json::booleanValue, false);
mutable_executor.set_use_strict_file_interactability(use_strict_file_interactability.asBool());

Json::Value enable_persistent_hover = this->GetCapability(capabilities, ENABLE_PERSISTENT_HOVER_CAPABILITY, Json::booleanValue, true);
if (require_window_focus.asBool() || !enable_native_events.asBool()) {
// Setting "require_window_focus" implies SendInput() API, and does not therefore require
Expand Down
54 changes: 35 additions & 19 deletions cpp/iedriver/CommandHandlers/SendKeysCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,30 +118,25 @@ void SendKeysCommandHandler::ExecuteInternal(
&frame_locations);

if (this->IsFileUploadElement(element_wrapper)) {
// TODO: If strict file interactability is set on, check element
// interactability before uploading the file.
bool use_strict_file_interactability = executor.use_strict_file_interactability();
if (executor.use_strict_file_interactability()) {
std::string upload_error_description = "";
if (!this->IsElementInteractable(element_wrapper,
&upload_error_description)) {
response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,
upload_error_description);
return;
}
}
this->UploadFile(browser_wrapper, element_wrapper, executor, keys, response);
return;
}

bool displayed;
status_code = element_wrapper->IsDisplayed(true, &displayed);
if (status_code != WD_SUCCESS || !displayed) {
response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,
"Element cannot be interacted with via the keyboard because it is not displayed");
return;
}

if (!element_wrapper->IsEnabled()) {
std::string error_description = "";
bool is_interactable = IsElementInteractable(element_wrapper,
&error_description);
if (!is_interactable) {
response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,
"Element cannot be interacted with via the keyboard because it is not enabled");
return;
}

if (!element_wrapper->IsFocusable()) {
response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,
"Element cannot be interacted with via the keyboard because it is not focusable");
error_description);
return;
}

Expand All @@ -165,6 +160,27 @@ void SendKeysCommandHandler::ExecuteInternal(
}
}

bool SendKeysCommandHandler::IsElementInteractable(ElementHandle element_wrapper,
std::string* error_description) {
bool displayed;
int status_code = element_wrapper->IsDisplayed(true, &displayed);
if (status_code != WD_SUCCESS || !displayed) {
*error_description = "Element cannot be interacted with via the keyboard because it is not displayed";
return false;
}

if (!element_wrapper->IsEnabled()) {
*error_description = "Element cannot be interacted with via the keyboard because it is not enabled";
return false;
}

if (!element_wrapper->IsFocusable()) {
*error_description = "Element cannot be interacted with via the keyboard because it is not focusable";
return false;
}
return true;
}

Json::Value SendKeysCommandHandler::CreateActionSequencePayload(const IECommandExecutor& executor,
std::wstring* keys) {
bool shift_pressed = executor.input_manager()->is_shift_pressed();
Expand Down
2 changes: 2 additions & 0 deletions cpp/iedriver/CommandHandlers/SendKeysCommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class SendKeysCommandHandler : public IECommandHandler {
Response* response);
bool IsFileUploadElement(ElementHandle element_wrapper);
bool HasMultipleAttribute(ElementHandle element_wrapper);
bool IsElementInteractable(ElementHandle element_wrapper,
std::string* error_description);
bool VerifyPageHasFocus(BrowserHandle browser_wrapper);
bool WaitUntilElementFocused(IHTMLElement* element);
bool SetInsertionPoint(IHTMLElement* element);
Expand Down

0 comments on commit 47f4439

Please sign in to comment.