Commit 923a7c78 authored by John Chen's avatar John Chen Committed by Commit Bot

[ChromeDriver] Fix pointer action locations

Fix how pointer event locations are calculated in Perform Actions
command, in particular, fixing how relative pointer moves are handled.
This fixes all failures in WPT test perform_actions/pointer.py.

Bug: chromedriver:1897
Change-Id: If0bd79399e9376fe885ef9c26f20d775a4c7d6c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1507313Reviewed-by: default avatarLan Wei <lanwei@chromium.org>
Commit-Queue: John Chen <johnchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638744}
parent c41820ad
...@@ -23,6 +23,7 @@ MouseEvent::MouseEvent(MouseEventType type, ...@@ -23,6 +23,7 @@ MouseEvent::MouseEvent(MouseEventType type,
modifiers(modifiers), modifiers(modifiers),
buttons(buttons), buttons(buttons),
click_count(click_count), click_count(click_count),
origin(kViewPort),
element_id(std::string()), element_id(std::string()),
pointer_type(kMouse) {} pointer_type(kMouse) {}
...@@ -34,12 +35,14 @@ TouchEvent::TouchEvent(TouchEventType type, int x, int y) ...@@ -34,12 +35,14 @@ TouchEvent::TouchEvent(TouchEventType type, int x, int y)
: type(type), : type(type),
x(x), x(x),
y(y), y(y),
origin(kViewPort),
radiusX(1.0), radiusX(1.0),
radiusY(1.0), radiusY(1.0),
rotationAngle(0.0), rotationAngle(0.0),
force(1.0), force(1.0),
id(0), id(0),
element_id(std::string()) {} element_id(std::string()),
dispatch(true) {}
TouchEvent::TouchEvent(const TouchEvent& other) = default; TouchEvent::TouchEvent(const TouchEvent& other) = default;
......
...@@ -32,6 +32,9 @@ enum MouseButton { ...@@ -32,6 +32,9 @@ enum MouseButton {
// Specifies the event's pointer type. // Specifies the event's pointer type.
enum PointerType { kMouse = 0, kPen }; enum PointerType { kMouse = 0, kPen };
// Specifies the origin of pointer location.
enum OriginType { kViewPort, kPointer, kElement };
struct MouseEvent { struct MouseEvent {
MouseEvent(MouseEventType type, MouseEvent(MouseEventType type,
MouseButton button, MouseButton button,
...@@ -51,6 +54,7 @@ struct MouseEvent { ...@@ -51,6 +54,7 @@ struct MouseEvent {
int buttons; int buttons;
// |click_count| should not be negative. // |click_count| should not be negative.
int click_count; int click_count;
OriginType origin;
std::string element_id; std::string element_id;
PointerType pointer_type; PointerType pointer_type;
}; };
...@@ -74,12 +78,14 @@ struct TouchEvent { ...@@ -74,12 +78,14 @@ struct TouchEvent {
TouchEventType type; TouchEventType type;
int x; int x;
int y; int y;
OriginType origin;
double radiusX; double radiusX;
double radiusY; double radiusY;
double rotationAngle; double rotationAngle;
double force; double force;
int id; int id;
std::string element_id; std::string element_id;
bool dispatch;
}; };
// Specifies the type of the keyboard event. // Specifies the type of the keyboard event.
......
...@@ -1334,6 +1334,7 @@ Status ExecutePerformActions(Session* session, ...@@ -1334,6 +1334,7 @@ Status ExecutePerformActions(Session* session,
bool has_touch_start = false; bool has_touch_start = false;
int buttons = 0; int buttons = 0;
std::string button_type; std::string button_type;
OriginType origin_type = kPointer;
std::string element_id; std::string element_id;
for (size_t j = 0; j < actions->GetSize(); j++) { for (size_t j = 0; j < actions->GetSize(); j++) {
const base::DictionaryValue* pointer_action; const base::DictionaryValue* pointer_action;
...@@ -1344,10 +1345,18 @@ Status ExecutePerformActions(Session* session, ...@@ -1344,10 +1345,18 @@ Status ExecutePerformActions(Session* session,
pointer_action->GetDouble("x", &x); pointer_action->GetDouble("x", &x);
pointer_action->GetDouble("y", &y); pointer_action->GetDouble("y", &y);
const base::DictionaryValue* origin_dict; const base::DictionaryValue* origin_dict;
origin_type = kViewPort;
element_id = ""; element_id = "";
if (pointer_action->HasKey("origin") && if (pointer_action->HasKey("origin")) {
pointer_action->GetDictionary("origin", &origin_dict)) { if (pointer_action->GetDictionary("origin", &origin_dict)) {
origin_dict->GetString(GetElementKey(), &element_id); origin_type = kElement;
origin_dict->GetString(GetElementKey(), &element_id);
} else {
std::string origin;
pointer_action->GetString("origin", &origin);
if (origin == "pointer")
origin_type = kPointer;
}
} }
} }
...@@ -1360,6 +1369,7 @@ Status ExecutePerformActions(Session* session, ...@@ -1360,6 +1369,7 @@ Status ExecutePerformActions(Session* session,
MouseEvent event(StringToMouseEventType(action_type), MouseEvent event(StringToMouseEventType(action_type),
StringToMouseButton(button_type), x, y, 0, buttons, StringToMouseButton(button_type), x, y, 0, buttons,
click_count); click_count);
event.origin = origin_type;
event.element_id = element_id; event.element_id = element_id;
event.pointer_type = StringToPointerType(pointer_type); event.pointer_type = StringToPointerType(pointer_type);
mouse_events.push_back(event); mouse_events.push_back(event);
...@@ -1373,11 +1383,12 @@ Status ExecutePerformActions(Session* session, ...@@ -1373,11 +1383,12 @@ Status ExecutePerformActions(Session* session,
else if (action_type == "pointerUp") else if (action_type == "pointerUp")
has_touch_start = false; has_touch_start = false;
if (action_type != "pointerMove" || has_touch_start) { TouchEvent event(StringToTouchEventType(action_type), x, y);
TouchEvent event(StringToTouchEventType(action_type), x, y); event.origin = origin_type;
event.element_id = element_id; event.element_id = element_id;
touch_events.push_back(event); if (action_type == "pointerMove")
} event.dispatch = has_touch_start;
touch_events.push_back(event);
} }
} }
...@@ -1399,7 +1410,8 @@ Status ExecutePerformActions(Session* session, ...@@ -1399,7 +1410,8 @@ Status ExecutePerformActions(Session* session,
size_t max_list_length = size_t max_list_length =
std::max({longest_mouse_list_size, longest_touch_list_size, std::max({longest_mouse_list_size, longest_touch_list_size,
longest_key_list_size, tick_durations.size()}); longest_key_list_size, tick_durations.size()});
std::map<std::string, gfx::Point> element_center_point; std::vector<gfx::Point> mouse_locations(mouse_events_list.size());
std::vector<gfx::Point> touch_locations(touch_events_list.size());
int key_modifiers = 0; int key_modifiers = 0;
for (size_t i = 0; i < max_list_length; i++) { for (size_t i = 0; i < max_list_length; i++) {
std::list<KeyEvent> dispatch_key_events; std::list<KeyEvent> dispatch_key_events;
...@@ -1428,18 +1440,21 @@ Status ExecutePerformActions(Session* session, ...@@ -1428,18 +1440,21 @@ Status ExecutePerformActions(Session* session,
if (i < mouse_events_list[j].size() && if (i < mouse_events_list[j].size() &&
mouse_events_list[j][i].type != kPauseMouseEventType) { mouse_events_list[j][i].type != kPauseMouseEventType) {
MouseEvent event = mouse_events_list[j][i]; MouseEvent event = mouse_events_list[j][i];
if (!event.element_id.empty()) { if (event.type == kMovedMouseEventType) {
if (event.type == kMovedMouseEventType || if (event.origin == kPointer) {
element_center_point.find(event.element_id) == event.x += mouse_locations[j].x();
element_center_point.end()) { event.y += mouse_locations[j].y();
} else if (!event.element_id.empty()) {
int center_x = 0, center_y = 0; int center_x = 0, center_y = 0;
ElementInViewCenter(session, web_view, event.element_id, &center_x, ElementInViewCenter(session, web_view, event.element_id, &center_x,
&center_y); &center_y);
element_center_point[event.element_id] = event.x += center_x;
gfx::Point(center_x, center_y); event.y += center_y;
} }
event.x += element_center_point[event.element_id].x(); mouse_locations[j] = gfx::Point(event.x, event.y);
event.y += element_center_point[event.element_id].y(); } else {
event.x = mouse_locations[j].x();
event.y = mouse_locations[j].y();
} }
event.modifiers = key_modifiers; event.modifiers = key_modifiers;
dispatch_mouse_events.push_back(event); dispatch_mouse_events.push_back(event);
...@@ -1457,20 +1472,24 @@ Status ExecutePerformActions(Session* session, ...@@ -1457,20 +1472,24 @@ Status ExecutePerformActions(Session* session,
if (i < touch_events_list[j].size() && if (i < touch_events_list[j].size() &&
touch_events_list[j][i].type != kPause) { touch_events_list[j][i].type != kPause) {
TouchEvent event = touch_events_list[j][i]; TouchEvent event = touch_events_list[j][i];
if (!event.element_id.empty()) { if (event.type == kTouchMove) {
if (event.type == kTouchMove || if (event.origin == kPointer) {
element_center_point.find(event.element_id) == event.x += touch_locations[j].x();
element_center_point.end()) { event.y += touch_locations[j].y();
} else if (!event.element_id.empty()) {
int center_x = 0, center_y = 0; int center_x = 0, center_y = 0;
ElementInViewCenter(session, web_view, event.element_id, &center_x, ElementInViewCenter(session, web_view, event.element_id, &center_x,
&center_y); &center_y);
element_center_point[event.element_id] = event.x += center_x;
gfx::Point(center_x, center_y); event.y += center_y;
} }
event.x += element_center_point[event.element_id].x(); touch_locations[j] = gfx::Point(event.x, event.y);
event.y += element_center_point[event.element_id].y(); } else {
event.x = touch_locations[j].x();
event.y = touch_locations[j].y();
} }
dispatch_touch_events.push_back(event); if (event.dispatch)
dispatch_touch_events.push_back(event);
} }
} }
if (dispatch_touch_events.size() > 0) { if (dispatch_touch_events.size() > 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment