Commit 432b256b authored by Lan Wei's avatar Lan Wei Committed by Commit Bot

[ChromeDriver] Refactor ExecutePerformActions function

In ExecutePerformActions function, we dispatch key events first, mouse
events then touch events, but we should dispatch whatever actions come
first in the action sequence. This CL changes high level of structures
of processing actions and dispatching events in the action sequence,
and I still need to refactor some details when procession the actions
in a following CL.

Bug: 606367
Change-Id: I46e02e547d0e5d5c2ddcdc949efc6b141142ea2c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1759855Reviewed-by: default avatarJohn Chen <johnchen@chromium.org>
Commit-Queue: Lan Wei <lanwei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688692}
parent d634937a
......@@ -23,8 +23,6 @@ MouseEvent::MouseEvent(MouseEventType type,
modifiers(modifiers),
buttons(buttons),
click_count(click_count),
origin(kViewPort),
element_id(std::string()),
pointer_type(kMouse) {}
MouseEvent::MouseEvent(const MouseEvent& other) = default;
......@@ -35,13 +33,11 @@ TouchEvent::TouchEvent(TouchEventType type, int x, int y)
: type(type),
x(x),
y(y),
origin(kViewPort),
radiusX(1.0),
radiusY(1.0),
rotationAngle(0.0),
force(1.0),
id(0),
element_id(std::string()),
dispatch(true) {}
TouchEvent::TouchEvent(const TouchEvent& other) = default;
......
......@@ -54,8 +54,6 @@ struct MouseEvent {
int buttons;
// |click_count| should not be negative.
int click_count;
OriginType origin;
std::string element_id;
PointerType pointer_type;
};
......@@ -78,13 +76,11 @@ struct TouchEvent {
TouchEventType type;
int x;
int y;
OriginType origin;
double radiusX;
double radiusY;
double rotationAngle;
double force;
int id;
std::string element_id;
bool dispatch;
};
......
......@@ -617,7 +617,7 @@ Status ConvertKeysToKeyEvents(const base::string16& client_keys,
Status ConvertKeyActionToKeyEvent(const base::DictionaryValue* action_object,
base::DictionaryValue* input_state,
bool is_key_down,
std::vector<KeyEvent>* key_events) {
std::list<KeyEvent>* key_events) {
std::string raw_key;
if (!action_object->GetString("value", &raw_key))
return Status(kUnknownError, "missing 'value'");
......
......@@ -28,6 +28,6 @@ Status ConvertKeysToKeyEvents(const base::string16& keys,
Status ConvertKeyActionToKeyEvent(const base::DictionaryValue* action_object,
base::DictionaryValue* input_state,
bool is_key_down,
std::vector<KeyEvent>* client_key_events);
std::list<KeyEvent>* client_key_events);
#endif // CHROME_TEST_CHROMEDRIVER_KEY_CONVERTER_H_
......@@ -374,39 +374,6 @@ Status ProcessPauseAction(const base::DictionaryValue* action_item,
return Status(kOk);
}
// Implements "compute the tick duration" algorithm from W3C spec
// (https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration).
// For convenience, this function computes durations of all ticks, while the
// original algorithm computes duration of one tick.
void ComputeTickDurations(std::vector<int>* tick_durations,
const base::ListValue& actions_list) {
for (size_t i = 0; i < actions_list.GetSize(); i++) {
const base::DictionaryValue* action_sequence = nullptr;
actions_list.GetDictionary(i, &action_sequence);
const base::ListValue* actions = nullptr;
action_sequence->GetList("actions", &actions);
std::string type;
action_sequence->GetString("sourceType", &type);
for (size_t j = 0; j < actions->GetSize(); j++) {
const base::DictionaryValue* action = nullptr;
actions->GetDictionary(j, &action);
std::string subtype;
action->GetString("subtype", &subtype);
if (subtype == "pause" ||
(type == "pointer" && subtype == "pointerMove")) {
if (j >= tick_durations->size())
tick_durations->resize(j + 1);
int duration = 0;
GetOptionalInt(action, "duration", &duration);
if (duration > (*tick_durations)[j])
(*tick_durations)[j] = duration;
}
}
}
}
Status ElementInViewCenter(Session* session,
WebView* web_view,
std::string element_id,
......@@ -1033,7 +1000,7 @@ Status ExecuteTouchScroll(Session* session,
Status ProcessInputActionSequence(
Session* session,
const base::DictionaryValue* action_sequence,
std::unique_ptr<base::DictionaryValue>* action_sequence_result) {
std::vector<std::unique_ptr<base::DictionaryValue>>* action_list) {
std::string id;
std::string type;
const base::DictionaryValue* source;
......@@ -1062,9 +1029,6 @@ Status ProcessInputActionSequence(
pointer_type = "mouse";
}
}
(*action_sequence_result)->SetString("sourceType", type);
(*action_sequence_result)->SetString("pointerType", pointer_type);
(*action_sequence_result)->SetString("id", id);
bool found = false;
for (size_t i = 0; i < session->active_input_sources.GetSize(); i++) {
......@@ -1135,6 +1099,7 @@ Status ProcessInputActionSequence(
std::unique_ptr<base::ListValue> actions_result(new base::ListValue);
for (size_t i = 0; i < actions->GetSize(); i++) {
std::unique_ptr<base::DictionaryValue> action(new base::DictionaryValue());
const base::DictionaryValue* action_item;
if (!actions->GetDictionary(i, &action_item))
return Status(
......@@ -1188,6 +1153,7 @@ Status ProcessInputActionSequence(
action->SetString("value", key);
}
} else if (type == "pointer") {
action->SetString("pointerType", pointer_type);
std::string subtype;
if (!action_item->GetString("type", &subtype) ||
(subtype != "pointerUp" && subtype != "pointerDown" &&
......@@ -1258,9 +1224,8 @@ Status ProcessInputActionSequence(
return status;
}
}
actions_result->Append(std::move(action));
action_list->push_back(std::move(action));
}
(*action_sequence_result)->SetList("actions", std::move(actions_result));
return Status(kOk);
}
......@@ -1276,242 +1241,182 @@ Status ExecutePerformActions(Session* session,
return Status(kInvalidArgument, "'actions' must be an array");
// the processed actions
base::ListValue actions_list;
std::vector<std::vector<std::unique_ptr<base::DictionaryValue>>> actions_list;
for (size_t i = 0; i < actions_input->GetSize(); i++) {
std::unique_ptr<base::DictionaryValue> input_source_actions(
new base::DictionaryValue());
// proccess input action sequence
const base::DictionaryValue* action_sequence;
if (!actions_input->GetDictionary(i, &action_sequence))
return Status(kInvalidArgument, "each argument must be a dictionary");
Status status = ProcessInputActionSequence(session, action_sequence,
&input_source_actions);
std::vector<std::unique_ptr<base::DictionaryValue>> action_list;
Status status =
ProcessInputActionSequence(session, action_sequence, &action_list);
actions_list.push_back(std::move(action_list));
if (status.IsError())
return Status(kInvalidArgument, status);
actions_list.Append(std::move(input_source_actions));
}
std::string input_pointer_type;
std::set<std::string> pointer_id_set;
std::string type;
std::vector<std::vector<MouseEvent>> mouse_events_list;
std::vector<base::DictionaryValue*> mouse_input_states;
std::vector<gfx::Point> mouse_locations;
std::vector<std::vector<TouchEvent>> touch_events_list;
std::vector<base::DictionaryValue*> touch_input_states;
std::vector<gfx::Point> touch_locations;
std::vector<std::vector<KeyEvent>> key_events_list;
std::vector<base::DictionaryValue*> key_input_states;
size_t longest_mouse_list_size = 0;
size_t longest_touch_list_size = 0;
size_t longest_key_list_size = 0;
for (size_t i = 0; i < actions_list.GetSize(); i++) {
base::DictionaryValue* action_sequence;
actions_list.GetDictionary(i, &action_sequence);
const base::ListValue* actions;
action_sequence->GetList("actions", &actions);
DCHECK(actions);
action_sequence->GetString("sourceType", &type);
std::vector<base::DictionaryValue*> action_input_states;
std::map<std::string, gfx::Point> action_locations;
std::map<std::string, bool> has_touch_start;
std::map<std::string, int> buttons;
std::map<std::string, std::string> button_type;
int viewport_width = 0, viewport_height = 0;
int init_x = 0, init_y = 0;
size_t longest_action_list_size = 0;
for (size_t i = 0; i < actions_list.size(); i++) {
longest_action_list_size =
std::max(longest_action_list_size, actions_list[i].size());
}
for (size_t i = 0; i < longest_action_list_size; i++) {
// Implements "compute the tick duration" algorithm from W3C spec
// (https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration).
// This is the duration for actions in one tick.
int tick_duration = 0;
for (size_t j = 0; j < actions_list.size(); j++) {
if (actions_list[j].size() > i) {
const base::DictionaryValue* action = actions_list[j][i].get();
std::string id;
action_sequence->GetString("id", &id);
std::string type;
std::string action_type;
action->GetString("id", &id);
base::DictionaryValue* input_state;
if (!session->input_state_table.GetDictionary(id, &input_state))
return Status(kUnknownError, "missing input state");
// key actions
if (i == 0) {
if (pointer_id_set.find(id) != pointer_id_set.end())
return Status(kInvalidArgument, "'id' already exists");
pointer_id_set.insert(id);
action_input_states.push_back(input_state);
}
action->GetString("type", &type);
action->GetString("subtype", &action_type);
int duration = 0;
if (action_type == "pause") {
GetOptionalInt(action, "duration", &duration);
tick_duration = std::max(tick_duration, duration);
}
if (type == "key") {
std::list<KeyEvent> dispatch_key_events;
KeyEventBuilder builder;
std::vector<KeyEvent> key_events;
for (size_t j = 0; j < actions->GetSize(); j++) {
const base::DictionaryValue* action;
actions->GetDictionary(j, &action);
std::string subtype;
action->GetString("subtype", &subtype);
if (action_type != "pause") {
Status status = ConvertKeyActionToKeyEvent(action, input_state,
action_type == "keyDown",
&dispatch_key_events);
if (status.IsError())
return status;
if (subtype == "pause") {
key_events.push_back(builder.SetType(kPauseEventType)->Build());
} else {
Status status = ConvertKeyActionToKeyEvent(
action, input_state, subtype == "keyDown", &key_events);
if (dispatch_key_events.size() > 0) {
const KeyEvent& event = dispatch_key_events.front();
if (action_type == "keyDown") {
session->input_cancel_list.emplace_back(
action_input_states[j], nullptr, nullptr, &event);
session->sticky_modifiers |= KeyToKeyModifiers(event.key);
} else if (action_type == "keyUp") {
session->sticky_modifiers &= ~KeyToKeyModifiers(event.key);
}
Status status = web_view->DispatchKeyEvents(dispatch_key_events);
if (status.IsError())
return status;
}
}
longest_key_list_size =
std::max(key_events.size(), longest_key_list_size);
key_events_list.push_back(key_events);
key_input_states.push_back(input_state);
} else if (type == "pointer") {
std::string pointer_type;
action_sequence->GetString("pointerType", &pointer_type);
action->GetString("pointerType", &pointer_type);
if (i == 0) {
Status status = WindowViewportSize(
session, web_view, &viewport_width, &viewport_height);
if (status.IsError())
return status;
if (input_pointer_type.empty())
input_pointer_type = pointer_type;
input_state->GetInteger("x", &init_x);
input_state->GetInteger("y", &init_y);
action_locations.insert(
std::make_pair(id, gfx::Point(init_x, init_y)));
if (input_pointer_type != pointer_type) {
return Status(kInvalidArgument,
"multiple input pointer types are not supported now");
if (pointer_type == "mouse" || pointer_type == "pen")
buttons[id] = input_state->FindKey("pressed")->GetInt();
else if (pointer_type == "touch")
has_touch_start[id] = false;
}
std::string pointer_id;
action_sequence->GetString("id", &pointer_id);
if (pointer_id_set.find(pointer_id) != pointer_id_set.end())
return Status(kInvalidArgument, "'id' already exists");
pointer_id_set.insert(pointer_id);
std::vector<MouseEvent> mouse_events;
std::vector<TouchEvent> touch_events;
if (action_type != "pause") {
std::list<MouseEvent> dispatch_mouse_events;
std::list<TouchEvent> dispatch_touch_events;
double x = 0;
double y = 0;
bool has_touch_start = input_state->FindKey("pressed")->GetInt() != 0;
int buttons = input_state->FindKey("pressed")->GetInt();
std::string button_type;
OriginType origin_type = kPointer;
std::string element_id;
for (size_t j = 0; j < actions->GetSize(); j++) {
const base::DictionaryValue* pointer_action;
actions->GetDictionary(j, &pointer_action);
std::string action_type;
pointer_action->GetString("subtype", &action_type);
OriginType origin = kViewPort;
std::string element_id = "";
if (action_type == "pointerMove") {
pointer_action->GetDouble("x", &x);
pointer_action->GetDouble("y", &y);
action->GetDouble("x", &x);
action->GetDouble("y", &y);
const base::DictionaryValue* origin_dict;
origin_type = kViewPort;
element_id = "";
if (pointer_action->HasKey("origin")) {
if (pointer_action->GetDictionary("origin", &origin_dict)) {
origin_type = kElement;
if (action->HasKey("origin")) {
if (action->GetDictionary("origin", &origin_dict)) {
origin = kElement;
origin_dict->GetString(GetElementKey(), &element_id);
} else {
std::string origin;
pointer_action->GetString("origin", &origin);
if (origin == "pointer")
origin_type = kPointer;
std::string origin_str;
action->GetString("origin", &origin_str);
if (origin_str == "pointer")
origin = kPointer;
}
}
duration = 0;
GetOptionalInt(action, "duration", &duration);
tick_duration = std::max(tick_duration, duration);
}
if (pointer_type == "mouse" || pointer_type == "pen") {
int click_count = 0;
if (action_type == "pointerDown" || action_type == "pointerUp") {
pointer_action->GetString("button", &button_type);
std::string button;
action->GetString("button", &button);
button_type[id] = button;
click_count = 1;
} else if (buttons == 0) {
button_type.clear();
} else if (buttons[id] == 0) {
button_type[id].clear();
}
MouseEvent event(StringToMouseEventType(action_type),
StringToMouseButton(button_type), x, y, 0, buttons,
click_count);
event.origin = origin_type;
event.element_id = element_id;
StringToMouseButton(button_type[id]), x, y, 0,
buttons[id], click_count);
event.pointer_type = StringToPointerType(pointer_type);
mouse_events.push_back(event);
if (action_type == "pointerDown")
buttons |= StringToModifierMouseButton(button_type);
else if (action_type == "pointerUp")
buttons &= ~StringToModifierMouseButton(button_type);
} else if (pointer_type == "touch") {
if (action_type == "pointerDown")
has_touch_start = true;
buttons[id] |= StringToModifierMouseButton(button_type[id]);
else if (action_type == "pointerUp")
has_touch_start = false;
TouchEvent event(StringToTouchEventType(action_type), x, y);
event.origin = origin_type;
event.element_id = element_id;
if (action_type == "pointerMove")
event.dispatch = has_touch_start;
touch_events.push_back(event);
}
}
int init_x = 0;
int init_y = 0;
input_state->GetInteger("x", &init_x);
input_state->GetInteger("y", &init_y);
if (pointer_type == "mouse" || pointer_type == "pen") {
longest_mouse_list_size =
std::max(mouse_events.size(), longest_mouse_list_size);
mouse_events_list.push_back(mouse_events);
mouse_input_states.push_back(input_state);
mouse_locations.emplace_back(init_x, init_y);
} else if (pointer_type == "touch") {
longest_touch_list_size =
std::max(touch_events.size(), longest_touch_list_size);
touch_events_list.push_back(touch_events);
touch_input_states.push_back(input_state);
touch_locations.emplace_back(init_x, init_y);
}
}
}
std::vector<int> tick_durations;
ComputeTickDurations(&tick_durations, actions_list);
int viewport_width = 0, viewport_height = 0;
if (mouse_events_list.size() > 0 || touch_events_list.size() > 0) {
Status status = WindowViewportSize(session, web_view, &viewport_width,
&viewport_height);
if (status.IsError())
return status;
}
buttons[id] &= ~StringToModifierMouseButton(button_type[id]);
size_t max_list_length =
std::max({longest_mouse_list_size, longest_touch_list_size,
longest_key_list_size, tick_durations.size()});
for (size_t i = 0; i < max_list_length; i++) {
std::list<KeyEvent> dispatch_key_events;
for (size_t j = 0; j < key_events_list.size(); j++) {
if (i < key_events_list[j].size() &&
key_events_list[j][i].type != kPauseEventType) {
const KeyEvent& event = key_events_list[j][i];
dispatch_key_events.push_back(event);
if (event.type == kKeyDownEventType) {
session->input_cancel_list.emplace_back(key_input_states[j], nullptr,
nullptr, &event);
session->sticky_modifiers |= KeyToKeyModifiers(event.key);
} else if (event.type == kKeyUpEventType) {
session->sticky_modifiers &= ~KeyToKeyModifiers(event.key);
}
}
}
if (dispatch_key_events.size() > 0) {
Status status = web_view->DispatchKeyEvents(dispatch_key_events);
if (status.IsError())
return status;
}
std::list<MouseEvent> dispatch_mouse_events;
for (size_t j = 0; j < mouse_events_list.size(); j++) {
if (i < mouse_events_list[j].size() &&
mouse_events_list[j][i].type != kPauseMouseEventType) {
MouseEvent event = mouse_events_list[j][i];
if (event.type == kMovedMouseEventType) {
if (event.origin == kPointer) {
event.x += mouse_locations[j].x();
event.y += mouse_locations[j].y();
} else if (!event.element_id.empty()) {
if (origin == kPointer) {
event.x += action_locations[id].x();
event.y += action_locations[id].y();
} else if (!element_id.empty()) {
int center_x = 0, center_y = 0;
Status status = ElementInViewCenter(
session, web_view, event.element_id, &center_x, &center_y);
session, web_view, element_id, &center_x, &center_y);
if (status.IsError())
return status;
event.x += center_x;
event.y += center_y;
}
if (event.x < 0 || event.x > viewport_width || event.y < 0 ||
event.y > viewport_height)
event.y > viewport_height) {
return Status(kMoveTargetOutOfBounds);
mouse_locations[j] = gfx::Point(event.x, event.y);
}
action_locations[id] = gfx::Point(event.x, event.y);
} else {
event.x = mouse_locations[j].x();
event.y = mouse_locations[j].y();
event.x = action_locations[id].x();
event.y = action_locations[id].y();
}
event.modifiers = session->sticky_modifiers;
if (event.type == kPressedMouseEventType) {
......@@ -1529,38 +1434,36 @@ Status ExecutePerformActions(Session* session,
}
dispatch_mouse_events.push_back(event);
if (event.type == kPressedMouseEventType) {
session->input_cancel_list.emplace_back(mouse_input_states[j], &event,
nullptr, nullptr);
mouse_input_states[j]->SetInteger(
"pressed", mouse_input_states[j]->FindKey("pressed")->GetInt() |
session->input_cancel_list.emplace_back(
action_input_states[j], &event, nullptr, nullptr);
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() |
(1 << event.button));
} else if (event.type == kReleasedMouseEventType) {
mouse_input_states[j]->SetInteger(
"pressed", mouse_input_states[j]->FindKey("pressed")->GetInt() &
action_input_states[j]->SetInteger(
"pressed",
action_input_states[j]->FindKey("pressed")->GetInt() &
~(1 << event.button));
}
}
}
if (dispatch_mouse_events.size() > 0) {
Status status = web_view->DispatchMouseEvents(
dispatch_mouse_events, session->GetCurrentFrameId());
if (status.IsError())
return status;
}
} else if (pointer_type == "touch") {
if (action_type == "pointerDown")
has_touch_start[id] = true;
std::list<TouchEvent> dispatch_touch_events;
for (size_t j = 0; j < touch_events_list.size(); j++) {
if (i < touch_events_list[j].size() &&
touch_events_list[j][i].type != kPause) {
TouchEvent event = touch_events_list[j][i];
TouchEvent event(StringToTouchEventType(action_type), x, y);
if (event.type == kTouchMove) {
if (event.origin == kPointer) {
event.x += touch_locations[j].x();
event.y += touch_locations[j].y();
} else if (!event.element_id.empty()) {
if (origin == kPointer) {
event.x += action_locations[id].x();
event.y += action_locations[id].y();
} else if (!element_id.empty()) {
int center_x = 0, center_y = 0;
Status status = ElementInViewCenter(
session, web_view, event.element_id, &center_x, &center_y);
session, web_view, element_id, &center_x, &center_y);
if (status.IsError())
return status;
event.x += center_x;
......@@ -1569,41 +1472,39 @@ Status ExecutePerformActions(Session* session,
if (event.x < 0 || event.x > viewport_width || event.y < 0 ||
event.y > viewport_height)
return Status(kMoveTargetOutOfBounds);
touch_locations[j] = gfx::Point(event.x, event.y);
action_locations[id] = gfx::Point(event.x, event.y);
} else {
event.x = touch_locations[j].x();
event.y = touch_locations[j].y();
event.x = action_locations[id].x();
event.y = action_locations[id].y();
}
if (event.dispatch)
dispatch_touch_events.push_back(event);
if (event.type == kTouchStart) {
session->input_cancel_list.emplace_back(touch_input_states[j],
nullptr, &event, nullptr);
touch_input_states[j]->SetInteger("pressed", 1);
session->input_cancel_list.emplace_back(
action_input_states[j], nullptr, &event, nullptr);
action_input_states[j]->SetInteger("pressed", 1);
} else if (event.type == kTouchEnd) {
touch_input_states[j]->SetInteger("pressed", 0);
}
}
action_input_states[j]->SetInteger("pressed", 0);
}
if (dispatch_touch_events.size() > 0) {
Status status = web_view->DispatchTouchEvents(dispatch_touch_events);
if (has_touch_start[id]) {
dispatch_touch_events.push_back(event);
Status status =
web_view->DispatchTouchEvents(dispatch_touch_events);
if (status.IsError())
return status;
}
if (action_type == "pointerUp")
has_touch_start[id] = false;
}
}
action_input_states[j]->SetInteger("x", action_locations[id].x());
action_input_states[j]->SetInteger("y", action_locations[id].y());
}
if (i < tick_durations.size() && tick_durations[i] > 0) {
if (tick_duration > 0) {
base::PlatformThread::Sleep(
base::TimeDelta::FromMilliseconds(tick_durations[i]));
base::TimeDelta::FromMilliseconds(tick_duration));
}
}
for (size_t i = 0; i < mouse_events_list.size(); i++) {
mouse_input_states[i]->SetInteger("x", mouse_locations[i].x());
mouse_input_states[i]->SetInteger("y", mouse_locations[i].y());
}
for (size_t i = 0; i < touch_events_list.size(); i++) {
touch_input_states[i]->SetInteger("x", touch_locations[i].x());
touch_input_states[i]->SetInteger("y", touch_locations[i].y());
}
return Status(kOk);
......
......@@ -373,7 +373,7 @@ Status ExecutePerformActions(Session* session,
Status ProcessInputActionSequence(
Session* session,
const base::DictionaryValue* action_sequence,
std::unique_ptr<base::DictionaryValue>* result);
std::vector<std::unique_ptr<base::DictionaryValue>>* action_list);
Status ExecuteReleaseActions(Session* session,
WebView* web_view,
......
......@@ -66,7 +66,7 @@ TEST(WindowCommandsTest, ExecuteResume) {
TEST(WindowCommandsTest, ProcessInputActionSequencePointerMouse) {
Session session("1");
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
std::vector<std::unique_ptr<base::DictionaryValue>> action_list;
std::unique_ptr<base::DictionaryValue> action_sequence(
new base::DictionaryValue());
std::unique_ptr<base::ListValue> actions(new base::ListValue());
......@@ -94,12 +94,10 @@ TEST(WindowCommandsTest, ProcessInputActionSequencePointerMouse) {
action_sequence->SetList("actions", std::move(actions));
const base::DictionaryValue* input_action_sequence = action_sequence.get();
Status status =
ProcessInputActionSequence(&session, input_action_sequence, &result);
ProcessInputActionSequence(&session, input_action_sequence, &action_list);
ASSERT_TRUE(status.IsOk());
// check resulting action dictionary
const base::ListValue* actions_result;
const base::DictionaryValue* action_result;
std::string pointer_type;
std::string source_type;
std::string id;
......@@ -107,37 +105,49 @@ TEST(WindowCommandsTest, ProcessInputActionSequencePointerMouse) {
int x, y;
std::string button;
result->GetString("sourceType", &source_type);
result->GetString("pointerType", &pointer_type);
result->GetString("id", &id);
ASSERT_EQ(3U, action_list.size());
const base::DictionaryValue* action1 = action_list[0].get();
action1->GetString("type", &source_type);
action1->GetString("pointerType", &pointer_type);
action1->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("mouse", pointer_type);
ASSERT_EQ("pointer1", id);
result->GetList("actions", &actions_result);
ASSERT_EQ(3U, actions_result->GetSize());
actions_result->GetDictionary(0, &action_result);
action_result->GetString("subtype", &action_type);
action_result->GetInteger("x", &x);
action_result->GetInteger("y", &y);
action1->GetString("subtype", &action_type);
action1->GetInteger("x", &x);
action1->GetInteger("y", &y);
ASSERT_EQ("pointerMove", action_type);
ASSERT_EQ(30, x);
ASSERT_EQ(60, y);
actions_result->GetDictionary(1, &action_result);
action_result->GetString("subtype", &action_type);
action_result->GetString("button", &button);
const base::DictionaryValue* action2 = action_list[1].get();
action2->GetString("type", &source_type);
action2->GetString("pointerType", &pointer_type);
action2->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("mouse", pointer_type);
ASSERT_EQ("pointer1", id);
action2->GetString("subtype", &action_type);
action2->GetString("button", &button);
ASSERT_EQ("pointerDown", action_type);
ASSERT_EQ("left", button);
actions_result->GetDictionary(2, &action_result);
action_result->GetString("subtype", &action_type);
action_result->GetString("button", &button);
const base::DictionaryValue* action3 = action_list[2].get();
action3->GetString("type", &source_type);
action3->GetString("pointerType", &pointer_type);
action3->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("mouse", pointer_type);
ASSERT_EQ("pointer1", id);
action3->GetString("subtype", &action_type);
action3->GetString("button", &button);
ASSERT_EQ("pointerUp", action_type);
ASSERT_EQ("left", button);
}
TEST(WindowCommandsTest, ProcessInputActionSequencePointerTouch) {
Session session("1");
std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
std::vector<std::unique_ptr<base::DictionaryValue>> action_list;
std::unique_ptr<base::DictionaryValue> action_sequence(
new base::DictionaryValue());
std::unique_ptr<base::ListValue> actions(new base::ListValue());
......@@ -163,38 +173,48 @@ TEST(WindowCommandsTest, ProcessInputActionSequencePointerTouch) {
action_sequence->SetList("actions", std::move(actions));
const base::DictionaryValue* input_action_sequence = action_sequence.get();
Status status =
ProcessInputActionSequence(&session, input_action_sequence, &result);
ProcessInputActionSequence(&session, input_action_sequence, &action_list);
ASSERT_TRUE(status.IsOk());
// check resulting action dictionary
const base::ListValue* actions_result;
const base::DictionaryValue* action_result;
std::string pointer_type;
std::string source_type;
std::string id;
std::string action_type;
int x, y;
result->GetString("sourceType", &source_type);
result->GetString("pointerType", &pointer_type);
result->GetString("id", &id);
ASSERT_EQ(3U, action_list.size());
const base::DictionaryValue* action1 = action_list[0].get();
action1->GetString("type", &source_type);
action1->GetString("pointerType", &pointer_type);
action1->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("touch", pointer_type);
ASSERT_EQ("pointer1", id);
result->GetList("actions", &actions_result);
ASSERT_EQ(3U, actions_result->GetSize());
actions_result->GetDictionary(0, &action_result);
action_result->GetString("subtype", &action_type);
action_result->GetInteger("x", &x);
action_result->GetInteger("y", &y);
action1->GetString("subtype", &action_type);
action1->GetInteger("x", &x);
action1->GetInteger("y", &y);
ASSERT_EQ("pointerMove", action_type);
ASSERT_EQ(30, x);
ASSERT_EQ(60, y);
actions_result->GetDictionary(1, &action_result);
action_result->GetString("subtype", &action_type);
const base::DictionaryValue* action2 = action_list[1].get();
action2->GetString("type", &source_type);
action2->GetString("pointerType", &pointer_type);
action2->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("touch", pointer_type);
ASSERT_EQ("pointer1", id);
action2->GetString("subtype", &action_type);
ASSERT_EQ("pointerDown", action_type);
actions_result->GetDictionary(2, &action_result);
action_result->GetString("subtype", &action_type);
const base::DictionaryValue* action3 = action_list[2].get();
action3->GetString("type", &source_type);
action3->GetString("pointerType", &pointer_type);
action3->GetString("id", &id);
ASSERT_EQ("pointer", source_type);
ASSERT_EQ("touch", pointer_type);
ASSERT_EQ("pointer1", id);
action3->GetString("subtype", &action_type);
ASSERT_EQ("pointerUp", action_type);
}
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