Skip to content

Commit f02168e

Browse files
committed
WIP: quick1 web view support
1 parent 9246a1e commit f02168e

File tree

5 files changed

+157
-12
lines changed

5 files changed

+157
-12
lines changed

inc/extension_qt/declarative_item_view_handle.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "webdriver_view_id.h"
77

88
#include <QtDeclarative/QDeclarativeItem>
9+
#include <QtDeclarative/QDeclarativeView>
910
#include <QtCore/QPointer>
1011
#include <QtCore/QtGlobal>
1112

@@ -14,14 +15,16 @@ namespace webdriver {
1415
class QDeclarativeItemViewHandle : public ViewHandle {
1516
public:
1617
QDeclarativeItemViewHandle();
17-
QDeclarativeItemViewHandle(QDeclarativeItem* view);
18+
QDeclarativeItemViewHandle(QDeclarativeItem* view, QDeclarativeView* container);
1819

1920
virtual bool is_valid() const { return !view_.isNull(); };
2021
virtual bool equals(const ViewHandle* other) const;
2122
QDeclarativeItem* get() { return view_.data(); };
23+
QDeclarativeView* getContainer() { return container_.data(); };
2224

2325
protected:
2426
QPointer<QDeclarativeItem> view_;
27+
QPointer<QDeclarativeView> container_;
2528
//private:
2629
virtual ~QDeclarativeItemViewHandle() {};
2730
};

inc/extension_qt/qml_web_view_executor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include <QtCore/QDebug>
1313

14+
class QDeclarativeView;
15+
1416
namespace webdriver {
1517

1618
class QWebkitProxy;
@@ -134,6 +136,7 @@ class QmlWebViewCmdExecutor : public ViewCmdExecutor {
134136
private:
135137
QWebkitProxy* webkitProxy_;
136138
QDeclarativeWebView* view_;
139+
QDeclarativeView* container_;
137140

138141
DISALLOW_COPY_AND_ASSIGN(QmlWebViewCmdExecutor);
139142
};

src/webdriver/extension_qt/declarative_item_view_handle.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
namespace webdriver {
44

55
QDeclarativeItemViewHandle::QDeclarativeItemViewHandle()
6-
: view_((QDeclarativeItem*)NULL) { }
6+
: view_(NULL), container_(NULL) { }
77

8-
QDeclarativeItemViewHandle::QDeclarativeItemViewHandle(QDeclarativeItem* view)
9-
: view_(view) { }
8+
QDeclarativeItemViewHandle::QDeclarativeItemViewHandle(QDeclarativeItem* view, QDeclarativeView* container)
9+
: view_(view), container_(container) { }
1010

1111
bool QDeclarativeItemViewHandle::equals(const ViewHandle* other) const {
1212
const QDeclarativeItemViewHandle* toCompare = dynamic_cast<const QDeclarativeItemViewHandle*>(other);
1313
if (NULL == toCompare) return false;
1414

15-
return view_ == toCompare->view_;
15+
return (view_ == toCompare->view_)&&(container_ == toCompare->container_);
1616
}
1717

1818
} // namespace webdriver

src/webdriver/extension_qt/qml_web_view_enumerator.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void QmlWebViewEnumeratorImpl::EnumerateViews(Session* session, std::set<ViewId>
3131
foreach(QDeclarativeItem *child, childs) {
3232
if (isWebView(child)) {
3333
// found
34-
ViewHandlePtr handle(new QDeclarativeItemViewHandle(child));
34+
ViewHandlePtr handle(new QDeclarativeItemViewHandle(child, pView));
3535
ViewId viewId = session->GetViewForHandle(handle);
3636
if (!viewId.is_valid()) {
3737
if (session->AddNewView(handle, &viewId)) {

src/webdriver/extension_qt/qml_web_view_executor.cc

Lines changed: 145 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
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

1419
namespace 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+
3754
QmlWebViewCmdExecutorCreator::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

114132
void 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

118165
void QmlWebViewCmdExecutor::GoForward(Error** error) {
@@ -164,19 +211,111 @@ void QmlWebViewCmdExecutor::MouseClick(MouseButton button, Error** error) {
164211
}
165212

166213
void 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

170233
void 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

174257
void 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

178289
void 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

182321
void QmlWebViewCmdExecutor::GetAttribute(const ElementId& element, const std::string& key, base::Value** value, Error** error) {

0 commit comments

Comments
 (0)