Skip to content

Commit 0c10a88

Browse files
committed
Updating IE driver findElement command handlers to be spec compliant
1 parent e8abd35 commit 0c10a88

File tree

4 files changed

+263
-161
lines changed

4 files changed

+263
-161
lines changed

cpp/iedriver/CommandHandlers/FindChildElementCommandHandler.cpp

Lines changed: 74 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -39,60 +39,86 @@ void FindChildElementCommandHandler::ExecuteInternal(
3939
if (id_parameter_iterator == command_parameters.end()) {
4040
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter in URL: id");
4141
return;
42-
} else if (using_parameter_iterator == command_parameters.end()) {
42+
}
43+
if (using_parameter_iterator == command_parameters.end()) {
4344
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: using");
4445
return;
45-
} else if (value_parameter_iterator == command_parameters.end()) {
46+
}
47+
if (!using_parameter_iterator->second.isString()) {
48+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter must be a string");
49+
return;
50+
}
51+
if (value_parameter_iterator == command_parameters.end()) {
4652
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: value");
4753
return;
48-
} else {
49-
std::string mechanism = using_parameter_iterator->second.asString();
50-
std::string value = value_parameter_iterator->second.asString();
51-
std::string element_id = id_parameter_iterator->second.asString();
52-
53-
ElementHandle parent_element_wrapper;
54-
int status_code = this->GetElement(executor,
55-
element_id,
56-
&parent_element_wrapper);
57-
58-
if (status_code == WD_SUCCESS) {
59-
Json::Value found_element;
60-
61-
int timeout = executor.implicit_wait_timeout();
62-
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
63-
if (timeout > 0 && timeout < 1000) {
64-
end += 1 * CLOCKS_PER_SEC;
65-
}
54+
}
55+
if (!value_parameter_iterator->second.isString()) {
56+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "value parameter must be a string");
57+
return;
58+
}
59+
60+
std::string mechanism = using_parameter_iterator->second.asString();
61+
std::string value = value_parameter_iterator->second.asString();
62+
std::string element_id = id_parameter_iterator->second.asString();
63+
64+
if (mechanism != "css selector" &&
65+
mechanism != "tag name" &&
66+
mechanism != "link text" &&
67+
mechanism != "partial link text" &&
68+
mechanism != "xpath") {
69+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter value '" + mechanism + "' is not a valid value");
70+
return;
71+
}
6672

67-
do {
68-
status_code = executor.LocateElement(parent_element_wrapper,
69-
mechanism,
70-
value,
71-
&found_element);
72-
if (status_code == WD_SUCCESS) {
73-
response->SetSuccessResponse(found_element);
74-
return;
75-
}
76-
if (status_code == ENOSUCHWINDOW) {
77-
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find element on closed window");
78-
return;
79-
}
80-
if (status_code != ENOSUCHELEMENT) {
81-
response->SetErrorResponse(status_code, found_element.asString());
82-
return;
83-
}
84-
85-
// Release the thread so that the browser doesn't starve.
86-
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
87-
} while (clock() < end);
88-
89-
// This code is executed when status_code == ENOSUCHELEMENT
90-
response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT,
91-
"Unable to find element with " + mechanism + " == " + value);
92-
} else {
93-
response->SetErrorResponse(status_code, "Element is no longer valid");
94-
return;
73+
BrowserHandle browser_wrapper;
74+
int status_code = executor.GetCurrentBrowser(&browser_wrapper);
75+
if (status_code != WD_SUCCESS) {
76+
response->SetErrorResponse(status_code, "Currently focused window has been closed.");
77+
return;
78+
}
79+
80+
ElementHandle parent_element_wrapper;
81+
status_code = this->GetElement(executor,
82+
element_id,
83+
&parent_element_wrapper);
84+
85+
if (status_code == WD_SUCCESS) {
86+
Json::Value found_element;
87+
88+
int timeout = executor.implicit_wait_timeout();
89+
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
90+
if (timeout > 0 && timeout < 1000) {
91+
end += 1 * CLOCKS_PER_SEC;
9592
}
93+
94+
do {
95+
status_code = executor.LocateElement(parent_element_wrapper,
96+
mechanism,
97+
value,
98+
&found_element);
99+
if (status_code == WD_SUCCESS) {
100+
response->SetSuccessResponse(found_element);
101+
return;
102+
}
103+
if (status_code == ENOSUCHWINDOW) {
104+
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find element on closed window");
105+
return;
106+
}
107+
if (status_code != ENOSUCHELEMENT) {
108+
response->SetErrorResponse(status_code, found_element.asString());
109+
return;
110+
}
111+
112+
// Release the thread so that the browser doesn't starve.
113+
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
114+
} while (clock() < end);
115+
116+
// This code is executed when status_code == ENOSUCHELEMENT
117+
response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT,
118+
"Unable to find element with " + mechanism + " == " + value);
119+
} else {
120+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Element is no longer valid");
121+
return;
96122
}
97123
}
98124

cpp/iedriver/CommandHandlers/FindChildElementsCommandHandler.cpp

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -38,64 +38,90 @@ void FindChildElementsCommandHandler::ExecuteInternal(
3838
if (id_parameter_iterator == command_parameters.end()) {
3939
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter in URL: id");
4040
return;
41-
} else if (using_parameter_iterator == command_parameters.end()) {
41+
}
42+
if (using_parameter_iterator == command_parameters.end()) {
4243
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: using");
4344
return;
44-
} else if (value_parameter_iterator == command_parameters.end()) {
45+
}
46+
if (!using_parameter_iterator->second.isString()) {
47+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter must be a string");
48+
return;
49+
}
50+
if (value_parameter_iterator == command_parameters.end()) {
4551
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: value");
4652
return;
47-
} else {
48-
std::string mechanism = using_parameter_iterator->second.asString();
49-
std::string value = value_parameter_iterator->second.asString();
50-
std::string element_id = id_parameter_iterator->second.asString();
53+
}
54+
if (!value_parameter_iterator->second.isString()) {
55+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "value parameter must be a string");
56+
return;
57+
}
5158

52-
ElementHandle parent_element_wrapper;
53-
int status_code = this->GetElement(executor,
54-
element_id,
55-
&parent_element_wrapper);
59+
std::string mechanism = using_parameter_iterator->second.asString();
60+
std::string value = value_parameter_iterator->second.asString();
61+
std::string element_id = id_parameter_iterator->second.asString();
5662

57-
if (status_code == WD_SUCCESS) {
58-
Json::Value found_elements(Json::arrayValue);
63+
if (mechanism != "css selector" &&
64+
mechanism != "tag name" &&
65+
mechanism != "link text" &&
66+
mechanism != "partial link text" &&
67+
mechanism != "xpath") {
68+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter value '" + mechanism + "' is not a valid value");
69+
return;
70+
}
5971

60-
int timeout = executor.implicit_wait_timeout();
61-
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
62-
if (timeout > 0 && timeout < 1000) {
63-
end += 1 * CLOCKS_PER_SEC;
64-
}
72+
BrowserHandle browser_wrapper;
73+
int status_code = executor.GetCurrentBrowser(&browser_wrapper);
74+
if (status_code != WD_SUCCESS) {
75+
response->SetErrorResponse(status_code, "Currently focused window has been closed.");
76+
return;
77+
}
6578

66-
do {
67-
status_code = executor.LocateElements(parent_element_wrapper,
68-
mechanism,
69-
value,
70-
&found_elements);
71-
if (status_code == WD_SUCCESS) {
72-
if (found_elements.isArray() && found_elements.size() > 0) {
73-
response->SetSuccessResponse(found_elements);
74-
return;
75-
}
76-
} else if (status_code == ENOSUCHWINDOW) {
77-
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find elements on closed window");
78-
return;
79-
} else {
80-
response->SetErrorResponse(status_code, found_elements.asString());
81-
return;
82-
}
79+
ElementHandle parent_element_wrapper;
80+
status_code = this->GetElement(executor,
81+
element_id,
82+
&parent_element_wrapper);
83+
84+
if (status_code == WD_SUCCESS) {
85+
Json::Value found_elements(Json::arrayValue);
8386

84-
// Release the thread so that the browser doesn't starve.
85-
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
86-
} while (clock() < end);
87+
int timeout = executor.implicit_wait_timeout();
88+
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
89+
if (timeout > 0 && timeout < 1000) {
90+
end += 1 * CLOCKS_PER_SEC;
91+
}
8792

88-
// This code is executed when no elements where found and no errors occurred.
93+
do {
94+
status_code = executor.LocateElements(parent_element_wrapper,
95+
mechanism,
96+
value,
97+
&found_elements);
8998
if (status_code == WD_SUCCESS) {
90-
response->SetSuccessResponse(found_elements);
99+
if (found_elements.isArray() && found_elements.size() > 0) {
100+
response->SetSuccessResponse(found_elements);
101+
return;
102+
}
103+
} else if (status_code == ENOSUCHWINDOW) {
104+
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find elements on closed window");
105+
return;
91106
} else {
92-
response->SetErrorResponse(status_code,
93-
"Finding elements with " + mechanism + " == " + value +
94-
"returned an unexpected error");
107+
response->SetErrorResponse(status_code, found_elements.asString());
108+
return;
95109
}
110+
111+
// Release the thread so that the browser doesn't starve.
112+
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
113+
} while (clock() < end);
114+
115+
// This code is executed when no elements where found and no errors occurred.
116+
if (status_code == WD_SUCCESS) {
117+
response->SetSuccessResponse(found_elements);
96118
} else {
97-
response->SetErrorResponse(status_code, "Element is no longer valid");
119+
response->SetErrorResponse(status_code,
120+
"Finding elements with " + mechanism + " == " + value +
121+
"returned an unexpected error");
98122
}
123+
} else {
124+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Element is no longer valid");
99125
}
100126
}
101127

cpp/iedriver/CommandHandlers/FindElementCommandHandler.cpp

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,47 +37,72 @@ void FindElementCommandHandler::ExecuteInternal(
3737
if (using_parameter_iterator == command_parameters.end()) {
3838
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: using");
3939
return;
40-
} else if (value_parameter_iterator == command_parameters.end()) {
40+
}
41+
if (!using_parameter_iterator->second.isString()) {
42+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter must be a string");
43+
return;
44+
}
45+
if (value_parameter_iterator == command_parameters.end()) {
4146
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "Missing parameter: value");
4247
return;
43-
} else {
44-
std::string mechanism = using_parameter_iterator->second.asString();
45-
std::string value = value_parameter_iterator->second.asString();
46-
47-
int timeout = executor.implicit_wait_timeout();
48-
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
49-
if (timeout > 0 && timeout < 1000) {
50-
end += 1 * CLOCKS_PER_SEC;
51-
}
48+
}
49+
if (!value_parameter_iterator->second.isString()) {
50+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "value parameter must be a string");
51+
return;
52+
}
5253

53-
int status_code = WD_SUCCESS;
54-
Json::Value found_element;
55-
do {
56-
status_code = executor.LocateElement(ElementHandle(),
57-
mechanism,
58-
value,
59-
&found_element);
60-
if (status_code == WD_SUCCESS) {
61-
response->SetSuccessResponse(found_element);
62-
return;
63-
}
64-
if (status_code == ENOSUCHWINDOW) {
65-
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find element on closed window");
66-
return;
67-
}
68-
if (status_code != ENOSUCHELEMENT) {
69-
response->SetErrorResponse(status_code, found_element.asString());
70-
return;
71-
}
54+
std::string mechanism = using_parameter_iterator->second.asString();
55+
std::string value = value_parameter_iterator->second.asString();
7256

73-
// Release the thread so that the browser doesn't starve.
74-
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
75-
} while (clock() < end);
57+
if (mechanism != "css selector" &&
58+
mechanism != "tag name" &&
59+
mechanism != "link text" &&
60+
mechanism != "partial link text" &&
61+
mechanism != "xpath") {
62+
response->SetErrorResponse(ERROR_INVALID_ARGUMENT, "using parameter value '" + mechanism + "' is not a valid value");
63+
return;
64+
}
7665

77-
response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT,
78-
"Unable to find element with " + mechanism + " == " + value);
66+
BrowserHandle browser_wrapper;
67+
int status_code = executor.GetCurrentBrowser(&browser_wrapper);
68+
if (status_code != WD_SUCCESS) {
69+
response->SetErrorResponse(status_code, "Currently focused window has been closed.");
7970
return;
8071
}
72+
73+
int timeout = executor.implicit_wait_timeout();
74+
clock_t end = clock() + (timeout / 1000 * CLOCKS_PER_SEC);
75+
if (timeout > 0 && timeout < 1000) {
76+
end += 1 * CLOCKS_PER_SEC;
77+
}
78+
79+
status_code = WD_SUCCESS;
80+
Json::Value found_element;
81+
do {
82+
status_code = executor.LocateElement(ElementHandle(),
83+
mechanism,
84+
value,
85+
&found_element);
86+
if (status_code == WD_SUCCESS) {
87+
response->SetSuccessResponse(found_element);
88+
return;
89+
}
90+
if (status_code == ENOSUCHWINDOW) {
91+
response->SetErrorResponse(ERROR_NO_SUCH_WINDOW, "Unable to find element on closed window");
92+
return;
93+
}
94+
if (status_code != ENOSUCHELEMENT) {
95+
response->SetErrorResponse(status_code, found_element.asString());
96+
return;
97+
}
98+
99+
// Release the thread so that the browser doesn't starve.
100+
::Sleep(FIND_ELEMENT_WAIT_TIME_IN_MILLISECONDS);
101+
} while (clock() < end);
102+
103+
response->SetErrorResponse(ERROR_NO_SUCH_ELEMENT,
104+
"Unable to find element with " + mechanism + " == " + value);
105+
return;
81106
}
82107

83108
} // namespace webdriver

0 commit comments

Comments
 (0)