Skip to content

Commit

Permalink
Render a mouse pointer when saving screenshots
Browse files Browse the repository at this point in the history
* Helpful for ClickFailed errors
  • Loading branch information
Joe Ferris and Matt Horan authored and youpy committed Jul 22, 2014
1 parent 9c11c8b commit c1b7700
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 18 deletions.
25 changes: 8 additions & 17 deletions src/JavascriptInvocation.cpp
Expand Up @@ -39,40 +39,31 @@ InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
void JavascriptInvocation::leftClick(int x, int y) {
QPoint mousePos(x, y);

hover(mousePos);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::LeftButton);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
m_page->mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::LeftButton);
m_page->mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
}

void JavascriptInvocation::rightClick(int x, int y) {
QPoint mousePos(x, y);

hover(mousePos);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::RightButton);
m_page->mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::RightButton);

// swallowContextMenuEvent tries to fire contextmenu event in html page
QContextMenuEvent *event = new QContextMenuEvent(QContextMenuEvent::Mouse, mousePos);
m_page->swallowContextMenuEvent(event);

JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::RightButton);
m_page->mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::RightButton);
}

void JavascriptInvocation::doubleClick(int x, int y) {
QPoint mousePos(x, y);

JavascriptInvocation::mouseEvent(QEvent::MouseButtonDblClick, mousePos, Qt::LeftButton);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
}

void JavascriptInvocation::mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button) {
QMouseEvent event(type, position, button, button, Qt::NoModifier);
QApplication::sendEvent(m_page, &event);
m_page->mouseEvent(QEvent::MouseButtonDblClick, mousePos, Qt::LeftButton);
m_page->mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
}

bool JavascriptInvocation::clickTest(QWebElement element, int absoluteX, int absoluteY) {
QPoint mousePos(absoluteX, absoluteY);
QWebHitTestResult res = m_page->mainFrame()->hitTestContent(mousePos);
return res.frame() == element.webFrame();
return m_page->clickTest(element, absoluteX, absoluteY);
}

QVariantMap JavascriptInvocation::clickPosition(QWebElement element, int left, int top, int width, int height) {
Expand Down Expand Up @@ -106,7 +97,7 @@ void JavascriptInvocation::hover(int absoluteX, int absoluteY) {
}

void JavascriptInvocation::hover(const QPoint &mousePos) {
mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
m_page->mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
}

int JavascriptInvocation::keyCodeFor(const QChar &key) {
Expand Down
1 change: 0 additions & 1 deletion src/JavascriptInvocation.h
Expand Up @@ -34,7 +34,6 @@ class JavascriptInvocation : public QObject {
QStringList m_arguments;
WebPage *m_page;
QVariant m_error;
void mouseEvent(QEvent::Type type, const QPoint & position, Qt::MouseButton button);
void hover(const QPoint &);
int keyCodeFor(const QChar &);
};
Expand Down
18 changes: 18 additions & 0 deletions src/WebPage.cpp
Expand Up @@ -10,6 +10,7 @@
#include <iostream>
#include <QWebSettings>
#include <QUuid>
#include <QApplication>

WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
m_loading = false;
Expand Down Expand Up @@ -214,6 +215,19 @@ QString WebPage::failureString() {
return message + m_errorPageMessage;
}

void WebPage::mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button) {
m_mousePosition = position;
QMouseEvent event(type, position, button, button, Qt::NoModifier);
QApplication::sendEvent(this, &event);
}

bool WebPage::clickTest(QWebElement element, int absoluteX, int absoluteY) {
QPoint mousePos(absoluteX, absoluteY);
m_mousePosition = mousePos;
QWebHitTestResult res = mainFrame()->hitTestContent(mousePos);
return res.frame() == element.webFrame();
}

bool WebPage::render(const QString &fileName, const QSize &minimumSize) {
QFileInfo fileInfo(fileName);
QDir dir;
Expand All @@ -236,6 +250,10 @@ bool WebPage::render(const QString &fileName, const QSize &minimumSize) {

this->setViewportSize(pageSize);
this->mainFrame()->render(&p);

QImage pointer = QImage(":/pointer.png");
p.drawImage(m_mousePosition, pointer);

p.end();
this->setViewportSize(viewportSize);

Expand Down
3 changes: 3 additions & 0 deletions src/WebPage.h
Expand Up @@ -44,6 +44,8 @@ class WebPage : public QWebPage {
QStringList pageHeaders();
QByteArray body();
QString contentType();
void mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button);
bool clickTest(QWebElement element, int absoluteX, int absoluteY);

public slots:
bool shouldInterruptJavaScript();
Expand Down Expand Up @@ -88,6 +90,7 @@ class WebPage : public QWebPage {
WebPageManager *m_manager;
QString m_errorPageMessage;
void setFrameProperties(QWebFrame *, QUrl &, NetworkReplyProxy *);
QPoint m_mousePosition;
};

#endif //_WEBPAGE_H
Expand Down
1 change: 1 addition & 0 deletions src/capybara.js
Expand Up @@ -189,6 +189,7 @@ Capybara = {
var node = this.nodes[index];
node.scrollIntoViewIfNeeded();
var pos = this.clickPosition(node);
CapybaraInvocation.hover(pos.relativeX, pos.relativeY);
this.expectNodeAtPosition(node, pos);
action(pos.absoluteX, pos.absoluteY);
},
Expand Down
Binary file added src/pointer.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/webkit_server.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>capybara.js</file>
<file>pointer.png</file>
</qresource>
</RCC>

0 comments on commit c1b7700

Please sign in to comment.