11#include " extension_qt/qml_web_view_executor.h"
22
3+ #include " base/stringprintf.h"
4+
35#include " webdriver_logging.h"
46#include " webdriver_session.h"
57#include " q_key_converter.h"
68#include " extension_qt/declarative_item_view_handle.h"
79#include " extension_qt/event_dispatcher.h"
810#include " extension_qt/wd_event_dispatcher.h"
11+ #include " common_util.h"
912#include " web_view_util.h"
1013#include " qwebkit_proxy.h"
1114
1215#include < QtCore/QDebug>
16+ #include < QtGui/QStyleOptionGraphicsItem>
17+ #include < QtGui/QApplication>
1318
1419namespace webdriver {
1520
1621#define CHECK_VIEW_EXISTANCE \
17- if (NULL == view_) { \
22+ if (( NULL == view_) || ( NULL == container_) ) { \
1823 session_->logger ().Log (kWarningLogLevel , " checkView - no such qml web view(" +view_id_.id ()+" )" ); \
1924 *error = new Error (kNoSuchWindow ); \
2025 return ; \
@@ -34,6 +39,18 @@ static QDeclarativeWebView* _getDeclarativeWebView(Session* session, const ViewI
3439 return qobject_cast<QDeclarativeWebView*>(qViewHandle->get ());
3540}
3641
42+ static QDeclarativeView* _getDeclarativeView (Session* session, const ViewId& viewId) {
43+ ViewHandle* viewHandle = session->GetViewHandle (viewId);
44+ if (NULL == viewHandle)
45+ return NULL ;
46+
47+ QDeclarativeItemViewHandle* qViewHandle = dynamic_cast <QDeclarativeItemViewHandle*>(viewHandle);
48+ if (NULL == qViewHandle)
49+ return NULL ;
50+
51+ return qobject_cast<QDeclarativeView*>(qViewHandle->getContainer ());
52+ }
53+
3754QmlWebViewCmdExecutorCreator::QmlWebViewCmdExecutorCreator ()
3855 : ViewCmdExecutorCreator() { }
3956
@@ -64,6 +81,7 @@ QmlWebViewCmdExecutor::QmlWebViewCmdExecutor(Session* session, ViewId viewId)
6481 : ViewCmdExecutor(session, viewId) {
6582
6683 view_ = _getDeclarativeWebView (session, viewId);
84+ container_ = _getDeclarativeView (session, viewId);
6785 webkitProxy_ = new QWebkitProxy (session, (view_)?view_->page ():NULL );
6886}
6987
@@ -112,7 +130,36 @@ void QmlWebViewCmdExecutor::GetBounds(Rect *bounds, Error **error) {
112130}
113131
114132void QmlWebViewCmdExecutor::GetScreenShot (std::string* png, Error** error) {
115- // TODO:
133+ CHECK_VIEW_EXISTANCE
134+
135+ QImage image (view_->boundingRect ().size ().toSize (), QImage::Format_RGB32);
136+ image.fill (QColor (0 , 0 , 0 ).rgb ());
137+ QPainter painter (&image);
138+ QStyleOptionGraphicsItem styleOption;
139+ qobject_cast<QGraphicsObject*>(view_)->paint (&painter, &styleOption);
140+ painter.end ();
141+
142+ const FilePath::CharType kPngFileName [] = FILE_PATH_LITERAL (" ./screen.png" );
143+ FilePath path = session_->temp_dir ().Append (kPngFileName );;
144+
145+ #if defined(OS_WIN)
146+ session_->logger ().Log (kInfoLogLevel , " Save screenshot to - " + path.MaybeAsASCII ());
147+ #elif defined(OS_POSIX)
148+ session_->logger ().Log (kInfoLogLevel , " Save screenshot to - " + path.value ());
149+ #endif
150+
151+ #if defined(OS_POSIX)
152+ if (!image.save (path.value ().c_str ()))
153+ #elif defined(OS_WIN)
154+ if (!image.save (QString::fromUtf16 ((ushort*)path.value ().c_str ())))
155+ #endif // OS_WIN
156+ {
157+ *error = new Error (kUnknownError , " screenshot was not captured" );
158+ return ;
159+ }
160+
161+ if (!file_util::ReadFileToString (path, png))
162+ *error = new Error (kUnknownError , " Could not read screenshot file" );
116163}
117164
118165void QmlWebViewCmdExecutor::GoForward (Error** error) {
@@ -164,19 +211,111 @@ void QmlWebViewCmdExecutor::MouseClick(MouseButton button, Error** error) {
164211}
165212
166213void QmlWebViewCmdExecutor::MouseMove (const int x_offset, const int y_offset, Error** error) {
167- // TODO:
214+ CHECK_VIEW_EXISTANCE
215+
216+ Point prev_pos = session_->get_mouse_position ();
217+ prev_pos.Offset (x_offset, y_offset);
218+
219+ QPoint point = QCommonUtil::ConvertPointToQPoint (prev_pos);
220+ QPointF scenePoint = view_->mapToScene (point.x (), point.y ());
221+
222+ QGraphicsSceneMouseEvent *moveEvent = new QGraphicsSceneMouseEvent (QEvent::GraphicsSceneMouseMove);
223+ moveEvent->setScenePos (scenePoint);
224+ QApplication::postEvent (container_->scene (), moveEvent);
225+
226+ session_->logger ().Log (kFineLogLevel , base::StringPrintf (" mouse move to: %d, %d" ,
227+ (int )scenePoint.x (),
228+ (int )scenePoint.y ()));
229+
230+ session_->set_mouse_position (prev_pos);
168231}
169232
170233void QmlWebViewCmdExecutor::MouseMove (const ElementId& element, int x_offset, const int y_offset, Error** error) {
171- // TODO:
234+ CHECK_VIEW_EXISTANCE
235+
236+ Point location;
237+ *error = webkitProxy_->GetElementLocationInView (element, &location);
238+ if (*error)
239+ return ;
240+
241+ location.Offset (x_offset, y_offset);
242+
243+ QPoint point = QCommonUtil::ConvertPointToQPoint (location);
244+ QPointF scenePoint = view_->mapToScene (point.x (), point.y ());
245+
246+ QGraphicsSceneMouseEvent *moveEvent = new QGraphicsSceneMouseEvent (QEvent::GraphicsSceneMouseMove);
247+ moveEvent->setScenePos (scenePoint);
248+ QApplication::postEvent (container_->scene (), moveEvent);
249+
250+ session_->logger ().Log (kFineLogLevel , base::StringPrintf (" mouse move to: %d, %d" ,
251+ (int )scenePoint.x (),
252+ (int )scenePoint.y ()));
253+
254+ session_->set_mouse_position (location);
172255}
173256
174257void QmlWebViewCmdExecutor::MouseMove (const ElementId& element, Error** error) {
175- // TODO:
258+ CHECK_VIEW_EXISTANCE
259+
260+ Point location;
261+
262+ // element is specified, calculate the coordinate.
263+ *error = webkitProxy_->GetElementLocationInView (element, &location);
264+ if (*error)
265+ return ;
266+
267+ // calculate the half of the element size and translate by it.
268+ Size size;
269+ *error = webkitProxy_->GetElementSize (element, &size);
270+ if (*error)
271+ return ;
272+
273+ location.Offset (size.width () / 2 , size.height () / 2 );
274+
275+ QPoint point = QCommonUtil::ConvertPointToQPoint (location);
276+ QPointF scenePoint = view_->mapToScene (point.x (), point.y ());
277+
278+ QGraphicsSceneMouseEvent *moveEvent = new QGraphicsSceneMouseEvent (QEvent::GraphicsSceneMouseMove);
279+ moveEvent->setScenePos (scenePoint);
280+ QApplication::postEvent (container_->scene (), moveEvent);
281+
282+ session_->logger ().Log (kFineLogLevel , base::StringPrintf (" mouse move to: %d, %d" ,
283+ (int )scenePoint.x (),
284+ (int )scenePoint.y ()));
285+
286+ session_->set_mouse_position (location);
176287}
177288
178289void QmlWebViewCmdExecutor::ClickElement (const ElementId& element, Error** error) {
179- // TODO:
290+ CHECK_VIEW_EXISTANCE
291+
292+ std::string tag_name;
293+ *error = webkitProxy_->GetElementTagName (element, &tag_name);
294+ if (*error)
295+ return ;
296+
297+ if (tag_name == " option" ) {
298+ bool can_be_toggled;
299+ *error = webkitProxy_->IsElementCanBeToggled (element, &can_be_toggled);
300+ if (*error)
301+ return ;
302+
303+ if (can_be_toggled) {
304+ *error = webkitProxy_->ToggleOptionElement (element);
305+ } else {
306+ *error = webkitProxy_->SetOptionElementSelected (element, true );
307+ }
308+ } else {
309+ Point location;
310+
311+ *error = webkitProxy_->GetClickableLocation (element, &location);
312+ if (!(*error)) {
313+ session_->logger ().Log (kFineLogLevel ,
314+ base::StringPrintf (" ClickElement at pos (%f, %f)." , location.x (), location.y ()));
315+ session_->set_mouse_position (location);
316+ MouseClick (kLeftButton , error);
317+ }
318+ }
180319}
181320
182321void QmlWebViewCmdExecutor::GetAttribute (const ElementId& element, const std::string& key, base::Value** value, Error** error) {
0 commit comments