Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: chrome/test/webdriver/session.cc

Issue 7465053: In chromedriver, check if an element is clickable before clicking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/webdriver/session.cc
diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc
index 54e60ef4e226cd3efeb824922bf5f8ac78952899..781ef2a48e57da9ada1b1adc785cffceaf5c6097 100644
--- a/chrome/test/webdriver/session.cc
+++ b/chrome/test/webdriver/session.cc
@@ -712,20 +712,22 @@ Error* Session::GetElementLocationInView(
return error;
return GetElementRegionInView(
element, gfx::Rect(gfx::Point(0, 0), size),
- false /* center */, location);
+ false /* center */, false /* verify_clickable_at_middle */, location);
}
Error* Session::GetElementRegionInView(
const WebElementId& element,
const gfx::Rect& region,
bool center,
+ bool verify_clickable_at_middle,
gfx::Point* location) {
CHECK(element.is_valid());
gfx::Point region_offset = region.origin();
gfx::Size region_size = region.size();
Error* error = GetElementRegionInViewHelper(
- current_target_, element, region, center, &region_offset);
+ current_target_, element, region, center, verify_clickable_at_middle,
+ &region_offset);
if (error)
return error;
@@ -756,7 +758,7 @@ Error* Session::GetElementRegionInView(
error = GetElementRegionInViewHelper(
frame_id, frame_element, gfx::Rect(region_offset, region_size),
- center, &region_offset);
+ center, verify_clickable_at_middle, &region_offset);
if (error)
return error;
}
@@ -963,7 +965,9 @@ Error* Session::GetClickableLocation(const WebElementId& element,
if (error)
return error;
- error = GetElementRegionInView(element, rect, true /* center */, location);
+ error = GetElementRegionInView(
+ element, rect, true /* center */, true /* verify_clickable_at_middle */,
+ location);
if (error)
return error;
location->Offset(rect.width() / 2, rect.height() / 2);
@@ -1311,11 +1315,58 @@ Error* Session::FindElementsHelper(const FrameId& frame_id,
return NULL;
}
+Error* Session::VerifyElementIsClickable(
+ const FrameId& frame_id,
+ const WebElementId& element,
+ const gfx::Point& location) {
+ std::string jscript = base::StringPrintf(
+ "return (%s).apply(null, arguments);", atoms::IS_ELEMENT_CLICKABLE);
+ ListValue jscript_args;
+ jscript_args.Append(element.ToValue());
+ DictionaryValue* location_dict = new DictionaryValue();
+ location_dict->SetInteger("x", location.x());
+ location_dict->SetInteger("y", location.y());
+ jscript_args.Append(location_dict);
+ Value* unscoped_value = NULL;
+ Error* error = ExecuteScript(frame_id, jscript, &jscript_args,
+ &unscoped_value);
+ if (error)
+ return error;
+
+ scoped_ptr<Value> value(unscoped_value);
+ if (!value->IsType(Value::TYPE_DICTIONARY)) {
+ return new Error(
+ kUnknownError,
+ "isElementClickable atom returned non-dictionary type: " +
+ JsonStringify(value.get()));
+ }
+ DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
+ bool clickable = false;
+ if (!dict->GetBoolean("clickable", &clickable)) {
+ return new Error(
+ kUnknownError,
+ "isElementClickable atom returned bad invalid dictionary: " +
+ JsonStringify(dict));
+ }
+ std::string message;
+ dict->GetString("message", &message);
+ if (!clickable) {
+ if (message.empty())
+ message = "element is not clickable";
+ return new Error(kUnknownError, message);
+ }
+ if (message.length()) {
+ LOG(WARNING) << message;
+ }
+ return NULL;
+}
+
Error* Session::GetElementRegionInViewHelper(
const FrameId& frame_id,
const WebElementId& element,
const gfx::Rect& region,
bool center,
+ bool verify_clickable_at_middle,
gfx::Point* location) {
std::string jscript = base::StringPrintf(
"return (%s).apply(null, arguments);", atoms::GET_LOCATION_IN_VIEW);
@@ -1334,6 +1385,7 @@ Error* Session::GetElementRegionInViewHelper(
scoped_ptr<Value> value(unscoped_value);
if (error)
return error;
+
if (!value->IsType(Value::TYPE_DICTIONARY)) {
return new Error(
kUnknownError,
@@ -1349,7 +1401,16 @@ Error* Session::GetElementRegionInViewHelper(
"Location atom returned bad coordinate dictionary: " +
JsonStringify(loc_dict));
}
- *location = gfx::Point(x, y);
+ gfx::Point temp_location = gfx::Point(x, y);
+
+ if (verify_clickable_at_middle) {
+ gfx::Point middle_point = temp_location;
+ middle_point.Offset(region.width() / 2, region.height() / 2);
+ error = VerifyElementIsClickable(frame_id, element, middle_point);
+ if (error)
+ return error;
+ }
+ *location = temp_location;
return NULL;
}

Powered by Google App Engine
This is Rietveld 408576698