added support for double and right click

This commit is contained in:
Michal Cichra 2013-02-25 10:28:43 +01:00 committed by Matthew Horan
parent 7d21f140cd
commit 89ad8b6811
5 changed files with 74 additions and 15 deletions

View File

@ -56,7 +56,15 @@ module Capybara::Webkit
end
def click
invoke("click")
invoke("leftClick")
end
def double_click
invoke("doubleClick")
end
def right_click
invoke("rightClick")
end
def drag_to(element)

View File

@ -991,9 +991,12 @@ describe Capybara::Webkit::Driver do
<ul id="events"></ul>
<script type="text/javascript">
var events = document.getElementById("events");
// https://developer.mozilla.org/en-US/docs/DOM/MouseEvent
var RIGHT_BUTTON = 2;
var recordEvent = function (event) {
var element = document.createElement("li");
element.innerHTML = event.type;
var type = event.button == RIGHT_BUTTON ? 'contextmenu' : event.type;
element.innerHTML = type;
events.appendChild(element);
};
@ -1003,6 +1006,8 @@ describe Capybara::Webkit::Driver do
element.addEventListener("mousedown", recordEvent);
element.addEventListener("mouseup", recordEvent);
element.addEventListener("click", recordEvent);
element.addEventListener("dblclick", recordEvent);
element.addEventListener("contextmenu", recordEvent);
}
</script>
</body></html>
@ -1011,9 +1016,23 @@ describe Capybara::Webkit::Driver do
before { visit("/") }
let(:watch) { driver.find_xpath("//a").first }
let(:fired_events) { driver.find_xpath("//li").map(&:visible_text) }
it "triggers mouse events" do
driver.find_xpath("//a").first.click
driver.find_xpath("//li").map(&:visible_text).should == %w(mousedown mouseup click)
watch.click
fired_events.should == %w(mousedown mouseup click)
end
it "triggers double click" do
# check event order at http://www.quirksmode.org/dom/events/click.html
watch.double_click
fired_events.should == %w(mousedown mouseup click mousedown mouseup click dblclick)
end
it "triggers right click" do
watch.right_click
fired_events.should == %w(contextmenu)
end
end

View File

@ -2,6 +2,7 @@
#include "WebPage.h"
#include "InvocationResult.h"
#include <QApplication>
#include <QEvent>
JavascriptInvocation::JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent) : QObject(parent) {
m_functionName = functionName;
@ -34,16 +35,30 @@ InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
return InvocationResult(result);
}
void JavascriptInvocation::click(int x, int y) {
void JavascriptInvocation::leftClick(int x, int y) {
QPoint mousePos(x, y);
QMouseEvent event(QEvent::MouseMove, mousePos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent(m_page, &event);
JavascriptInvocation::mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, mousePos, Qt::LeftButton);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton);
}
event = QMouseEvent(QEvent::MouseButtonPress, mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QApplication::sendEvent(m_page, &event);
void JavascriptInvocation::rightClick(int x, int y) {
QPoint mousePos(x, y);
event = QMouseEvent(QEvent::MouseButtonRelease, mousePos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
JavascriptInvocation::mouseEvent(QEvent::MouseMove, mousePos, Qt::NoButton);
JavascriptInvocation::mouseEvent(QEvent::MouseButtonPress, 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);
}

View File

@ -1,6 +1,7 @@
#include <QObject>
#include <QString>
#include <QStringList>
#include <QEvent>
#include <QWebElement>
class WebPage;
@ -16,7 +17,9 @@ class JavascriptInvocation : public QObject {
JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent = 0);
QString &functionName();
QStringList &arguments();
Q_INVOKABLE void click(int x, int y);
Q_INVOKABLE void leftClick(int x, int y);
Q_INVOKABLE void rightClick(int x, int y);
Q_INVOKABLE void doubleClick(int x, int y);
Q_INVOKABLE bool clickTest(QWebElement element, int absoluteX, int absoluteY);
Q_INVOKABLE QVariantMap clickPosition(QWebElement element, int left, int top, int width, int height);
QVariant getError();
@ -28,5 +31,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);
};

View File

@ -151,18 +151,31 @@ Capybara = {
return CapybaraInvocation.clickPosition(node, rect.left, rect.top, rect.width, rect.height);
},
click: function (index) {
click: function (index, action) {
var node = this.nodes[index];
node.scrollIntoViewIfNeeded();
var pos = this.clickPosition(node);
if (pos && this.clickTest(node, pos))
CapybaraInvocation.click(pos.absoluteX, pos.absoluteY);
action(pos.absoluteX, pos.absoluteY);
else
throw new Capybara.ClickFailed(this.path(index), pos);
},
leftClick: function (index) {
this.click(index, CapybaraInvocation.leftClick);
},
doubleClick: function(index) {
this.click(index, CapybaraInvocation.leftClick);
this.click(index, CapybaraInvocation.doubleClick);
},
rightClick: function(index) {
this.click(index, CapybaraInvocation.rightClick);
},
trigger: function (index, eventName) {
var eventObject = document.createEvent("HTMLEvents");
eventObject.initEvent(eventName, true, true);
@ -294,12 +307,12 @@ Capybara = {
} else if (type === "checkbox" || type === "radio") {
if (node.checked != (value === "true")) {
this.click(index);
this.leftClick(index);
}
} else if (type === "file") {
this.attachedFiles = Array.prototype.slice.call(arguments, 1);
this.click(index);
this.leftClick(index);
} else {
node.value = value;