Path: blob/trunk/cpp/iedriver/ActionSimulators/JavaScriptActionSimulator.cpp
2868 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the "License");5// you may not use this file except in compliance with the License.6// You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.1516#include "JavaScriptActionSimulator.h"1718#include "errorcodes.h"19#include "logging.h"2021#include "../DocumentHost.h"22#include "../Generated/atoms.h"23#include "../Script.h"2425#define WAIT_TIME_IN_MILLISECONDS_PER_INPUT_EVENT 1002627namespace webdriver {282930JavaScriptActionSimulator::JavaScriptActionSimulator() {31CComVariant keyboard_state;32keyboard_state.vt = VT_NULL;33this->keyboard_state_ = keyboard_state;3435CComVariant mouse_state;36mouse_state.vt = VT_NULL;37this->mouse_state_ = mouse_state;38}3940JavaScriptActionSimulator::~JavaScriptActionSimulator() {41}4243int JavaScriptActionSimulator::SimulateActions(BrowserHandle browser_wrapper,44std::vector<INPUT> inputs,45InputState* input_state) {46LOG(TRACE) << "Entering JavaScriptActionSimulator::SimulateActions";47for (size_t i = 0; i < inputs.size(); ++i) {48INPUT current_input = inputs[i];49this->UpdateInputState(current_input, input_state);50if (current_input.type == INPUT_MOUSE) {51if (current_input.mi.dwFlags & MOUSEEVENTF_MOVE) {52this->SimulatePointerMove(browser_wrapper, current_input);53} else if (current_input.mi.dwFlags & MOUSEEVENTF_LEFTDOWN) {54this->SimulatePointerDown(browser_wrapper, current_input);55} else if (current_input.mi.dwFlags & MOUSEEVENTF_LEFTUP) {56this->SimulatePointerUp(browser_wrapper, current_input);57} else if (current_input.mi.dwFlags & MOUSEEVENTF_RIGHTDOWN) {58this->SimulatePointerDown(browser_wrapper, current_input);59} else if (current_input.mi.dwFlags & MOUSEEVENTF_RIGHTUP) {60this->SimulatePointerUp(browser_wrapper, current_input);61}62} else if (current_input.type == INPUT_KEYBOARD) {63this->SimulateKeyDown(browser_wrapper, current_input);64} else if (current_input.type == INPUT_HARDWARE) {65::Sleep(current_input.hi.uMsg);66}67}68return WD_SUCCESS;69}7071int JavaScriptActionSimulator::SimulateKeyDown(BrowserHandle browser_wrapper,72INPUT input) {73KeyboardExtraInfo* extra_info = reinterpret_cast<KeyboardExtraInfo*>(input.ki.dwExtraInfo);74std::wstring key = extra_info->character;75delete extra_info;76LOG(DEBUG) << "Using synthetic events for sending keys";77std::wstring script_source = L"(function() { return function(){" +78atoms::asString(atoms::INPUTS_BIN) +79L"; return webdriver.atoms.inputs.sendKeys(" +80L"arguments[0], arguments[1], arguments[2], arguments[3]);" +81L"};})();";82CComPtr<IHTMLDocument2> doc;83browser_wrapper->GetDocument(&doc);84Script script_wrapper(doc, script_source, 4);8586script_wrapper.AddNullArgument();87script_wrapper.AddArgument(key);88script_wrapper.AddArgument(this->keyboard_state_);89script_wrapper.AddArgument(true);90int status_code = script_wrapper.Execute();91if (status_code == WD_SUCCESS) {92this->keyboard_state_ = script_wrapper.result();93} else {94LOG(WARN) << "Unable to execute js to send keystrokes";95}96return status_code;97}9899int JavaScriptActionSimulator::SimulatePointerMove(BrowserHandle browser_wrapper,100INPUT input) {101LOG(DEBUG) << "Using synthetic events for mouse move";102MouseExtraInfo* extra_info = reinterpret_cast<MouseExtraInfo*>(input.mi.dwExtraInfo);103int x_offset = extra_info->offset_x;104int y_offset = extra_info->offset_y;105bool is_offset_specified = extra_info->offset_specified;106CComPtr<IHTMLElement> target_element = extra_info->element;107delete extra_info;108109std::wstring script_source = L"(function() { return function(){" +110atoms::asString(atoms::INPUTS_BIN) +111L"; return webdriver.atoms.inputs.mouseMove(arguments[0], arguments[1], arguments[2], arguments[3]);" +112L"};})();";113114CComPtr<IHTMLDocument2> doc;115browser_wrapper->GetDocument(&doc);116Script script_wrapper(doc, script_source, 4);117118if (target_element != NULL) {119script_wrapper.AddArgument(target_element);120} else {121script_wrapper.AddNullArgument();122}123124if (is_offset_specified) {125script_wrapper.AddArgument(x_offset);126script_wrapper.AddArgument(y_offset);127} else {128script_wrapper.AddNullArgument();129script_wrapper.AddNullArgument();130}131132script_wrapper.AddArgument(this->mouse_state_);133int status_code = script_wrapper.Execute();134if (status_code == WD_SUCCESS) {135this->mouse_state_ = script_wrapper.result();136} else {137LOG(WARN) << "Unable to execute js to mouse move";138}139return status_code;140}141142int JavaScriptActionSimulator::SimulatePointerDown(BrowserHandle browser_wrapper,143INPUT input) {144LOG(DEBUG) << "Using synthetic events for mouse button down";145std::wstring script_source = L"(function() { return function(){" +146atoms::asString(atoms::INPUTS_BIN) +147L"; return webdriver.atoms.inputs.mouseButtonDown(arguments[0]);" +148L"};})();";149150CComPtr<IHTMLDocument2> doc;151browser_wrapper->GetDocument(&doc);152Script script_wrapper(doc, script_source, 1);153script_wrapper.AddArgument(this->mouse_state_);154int status_code = script_wrapper.Execute();155if (status_code == WD_SUCCESS) {156this->mouse_state_ = script_wrapper.result();157} else {158LOG(WARN) << "Unable to execute js to perform mouse button down";159return status_code;160}161return status_code;162}163164int JavaScriptActionSimulator::SimulatePointerUp(BrowserHandle browser_wrapper,165INPUT input) {166LOG(DEBUG) << "Using synthetic events for mouse button up";167std::wstring script_source = L"(function() { return function(){" +168atoms::asString(atoms::INPUTS_BIN) +169L"; return webdriver.atoms.inputs.mouseButtonUp(arguments[0]);" +170L"};})();";171172CComPtr<IHTMLDocument2> doc;173browser_wrapper->GetDocument(&doc);174Script script_wrapper(doc, script_source, 1);175script_wrapper.AddArgument(this->mouse_state_);176int status_code = script_wrapper.Execute();177if (status_code == WD_SUCCESS) {178this->mouse_state_ = script_wrapper.result();179} else {180LOG(WARN) << "Unable to execute js to perform mouse button up";181return status_code;182}183return status_code;184}185186int JavaScriptActionSimulator::SimulatePause(BrowserHandle browser_wrapper,187INPUT input) {188::Sleep(input.hi.uMsg);189return WD_SUCCESS;190}191192} // namespace webdriver193194195