Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/cpp/iedriver/CommandHandlers/ClearElementCommandHandler.cpp
2868 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
17
#include "ClearElementCommandHandler.h"
18
#include "errorcodes.h"
19
#include "../Browser.h"
20
#include "../Element.h"
21
#include "../IECommandExecutor.h"
22
#include "../Generated/atoms.h"
23
#include "../Script.h"
24
#include "../WebDriverConstants.h"
25
26
namespace webdriver {
27
28
ClearElementCommandHandler::ClearElementCommandHandler(void) {
29
}
30
31
ClearElementCommandHandler::~ClearElementCommandHandler(void) {
32
}
33
34
void ClearElementCommandHandler::ExecuteInternal(
35
const IECommandExecutor& executor,
36
const ParametersMap& command_parameters,
37
Response* response) {
38
ParametersMap::const_iterator id_parameter_iterator = command_parameters.find("id");
39
if (id_parameter_iterator == command_parameters.end()) {
40
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter in URL: id");
41
return;
42
} else {
43
int status_code = WD_SUCCESS;
44
std::string element_id = id_parameter_iterator->second.asString();
45
46
BrowserHandle browser_wrapper;
47
status_code = executor.GetCurrentBrowser(&browser_wrapper);
48
if (status_code != WD_SUCCESS) {
49
response->SetErrorResponse(status_code, "Unable to get browser");
50
return;
51
}
52
53
ElementHandle element_wrapper;
54
status_code = this->GetElement(executor, element_id, &element_wrapper);
55
if (status_code == WD_SUCCESS) {
56
// Yes, the clear atom should check this for us, but executing it asynchronously
57
// does not return the proper error code when this error condition is encountered.
58
// Thus, we'll check the interactable and editable states of the element before
59
// attempting to clear it.
60
if (!element_wrapper->IsEditable() || !element_wrapper->IsEnabled()) {
61
response->SetErrorResponse(ERROR_INVALID_ELEMENT_STATE,
62
"Element must not be read-only or disabled");
63
return;
64
}
65
if (!element_wrapper->IsInteractable()) {
66
response->SetErrorResponse(ERROR_ELEMENT_NOT_INTERACTABLE,
67
"Element is not interactable, it must not be hidden and it must be able to receive focus");
68
return;
69
}
70
71
// The atom is just the definition of an anonymous
72
// function: "function() {...}"; Wrap it in another function so we can
73
// invoke it with our arguments without polluting the current namespace.
74
std::wstring script_source = L"(function() { return (";
75
script_source += atoms::asString(atoms::CLEAR);
76
script_source += L")})();";
77
78
Json::Value args(Json::arrayValue);
79
args.append(element_wrapper->ConvertToJson());
80
81
HWND async_executor_handle;
82
CComPtr<IHTMLDocument2> doc;
83
browser_wrapper->GetDocument(&doc);
84
Script script_wrapper(doc, script_source);
85
status_code = script_wrapper.ExecuteAsync(executor,
86
args,
87
ASYNC_SCRIPT_EXECUTION_TIMEOUT_IN_MILLISECONDS,
88
&async_executor_handle);
89
if (status_code != WD_SUCCESS) {
90
// Assume that a JavaScript error returned by the atom is that
91
// the element is either invisible, disabled, or read-only.
92
// This may be a bad assumption, but we currently have no way
93
// to get information about exceptions thrown from JS.
94
response->SetErrorResponse(EELEMENTNOTENABLED,
95
"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.");
96
return;
97
}
98
} else if (status_code == ENOSUCHELEMENT) {
99
response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT, "Invalid internal element ID requested: " + element_id);
100
return;
101
} else {
102
response->SetErrorResponse(status_code, "Element is no longer valid");
103
return;
104
}
105
106
response->SetSuccessResponse(Json::Value::null);
107
}
108
}
109
110
} // namespace webdriver
111
112