Path: blob/trunk/cpp/iedriver/CommandHandlers/ClearElementCommandHandler.cpp
2868 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the "License");5// you may not use this file except in compliance with the License.6// You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.1516#include "ClearElementCommandHandler.h"17#include "errorcodes.h"18#include "../Browser.h"19#include "../Element.h"20#include "../IECommandExecutor.h"21#include "../Generated/atoms.h"22#include "../Script.h"23#include "../WebDriverConstants.h"2425namespace webdriver {2627ClearElementCommandHandler::ClearElementCommandHandler(void) {28}2930ClearElementCommandHandler::~ClearElementCommandHandler(void) {31}3233void ClearElementCommandHandler::ExecuteInternal(34const IECommandExecutor& executor,35const ParametersMap& command_parameters,36Response* response) {37ParametersMap::const_iterator id_parameter_iterator = command_parameters.find("id");38if (id_parameter_iterator == command_parameters.end()) {39response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter in URL: id");40return;41} else {42int status_code = WD_SUCCESS;43std::string element_id = id_parameter_iterator->second.asString();4445BrowserHandle browser_wrapper;46status_code = executor.GetCurrentBrowser(&browser_wrapper);47if (status_code != WD_SUCCESS) {48response->SetErrorResponse(status_code, "Unable to get browser");49return;50}5152ElementHandle element_wrapper;53status_code = this->GetElement(executor, element_id, &element_wrapper);54if (status_code == WD_SUCCESS) {55// Yes, the clear atom should check this for us, but executing it asynchronously56// does not return the proper error code when this error condition is encountered.57// Thus, we'll check the interactable and editable states of the element before58// attempting to clear it.59if (!element_wrapper->IsEditable() || !element_wrapper->IsEnabled()) {60response->SetErrorResponse(ERROR_INVALID_ELEMENT_STATE,61"Element must not be read-only or disabled");62return;63}64if (!element_wrapper->IsInteractable()) {65response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,66"Element is not interactable, it must not be hidden and it must be able to receive focus");67return;68}6970// The atom is just the definition of an anonymous71// function: "function() {...}"; Wrap it in another function so we can72// invoke it with our arguments without polluting the current namespace.73std::wstring script_source = L"(function() { return (";74script_source += atoms::asString(atoms::CLEAR);75script_source += L")})();";7677Json::Value args(Json::arrayValue);78args.append(element_wrapper->ConvertToJson());7980HWND async_executor_handle;81CComPtr<IHTMLDocument2> doc;82browser_wrapper->GetDocument(&doc);83Script script_wrapper(doc, script_source);84status_code = script_wrapper.ExecuteAsync(executor,85args,86ASYNC_SCRIPT_EXECUTION_TIMEOUT_IN_MILLISECONDS,87&async_executor_handle);88if (status_code != WD_SUCCESS) {89// Assume that a JavaScript error returned by the atom is that90// the element is either invisible, disabled, or read-only.91// This may be a bad assumption, but we currently have no way92// to get information about exceptions thrown from JS.93response->SetErrorResponse(EELEMENTNOTENABLED,94"A JavaScript error was encountered clearing the element. The driver assumes this is because the element is hidden, disabled or read-only, and it must not be to clear the element.");95return;96}97} else if (status_code == ENOSUCHELEMENT) {98response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT, "Invalid internal element ID requested: " + element_id);99return;100} else {101response->SetErrorResponse(status_code, "Element is no longer valid");102return;103}104105response->SetSuccessResponse(Json::Value::null);106}107}108109} // namespace webdriver110111112