Raise error when elements are unclickable
This commit is contained in:
parent
30c79fcfcb
commit
4837ff144c
|
@ -7,4 +7,7 @@ module Capybara::Webkit
|
|||
|
||||
class NodeNotAttachedError < Capybara::ElementNotFound
|
||||
end
|
||||
|
||||
class ClickFailed < StandardError
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,7 +54,9 @@ module Capybara::Webkit
|
|||
end
|
||||
|
||||
def click
|
||||
invoke "click"
|
||||
unless invoke("click") == "true"
|
||||
raise Capybara::Webkit::ClickFailed
|
||||
end
|
||||
end
|
||||
|
||||
def drag_to(element)
|
||||
|
|
|
@ -357,5 +357,20 @@ describe Capybara::Session do
|
|||
subject.find(:css, '#two')['data-click-x'].should_not be_nil
|
||||
subject.find(:css, '#two')['data-click-y'].should_not be_nil
|
||||
end
|
||||
|
||||
it 'raises an error if an element is obscured when clicked' do
|
||||
subject.visit('/')
|
||||
|
||||
subject.execute_script(<<-JS)
|
||||
var two = document.getElementById('two');
|
||||
two.style.position = 'absolute';
|
||||
two.style.left = '0px';
|
||||
two.style.top = '0px';
|
||||
JS
|
||||
|
||||
lambda {
|
||||
subject.find(:css, '#one').click
|
||||
}.should raise_error(Capybara::Webkit::ClickFailed)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,16 +16,28 @@ QStringList &JavascriptInvocation::arguments() {
|
|||
return m_arguments;
|
||||
}
|
||||
|
||||
void JavascriptInvocation::click(const QWebElement &element, int left, int top, int width, int height) {
|
||||
bool JavascriptInvocation::click(const QWebElement &element, int left, int top, int width, int height) {
|
||||
QRect elementBox(left, top, width, height);
|
||||
QWebFrame *parent = element.webFrame();
|
||||
while (parent) {
|
||||
elementBox = elementBox.translated(parent->geometry().topLeft());
|
||||
elementBox.translate(parent->geometry().topLeft());
|
||||
parent = parent->parentFrame();
|
||||
}
|
||||
QRect viewport(QPoint(0, 0), m_page->viewportSize());
|
||||
QPoint mousePos = elementBox.intersected(viewport).center();
|
||||
QRect boundedBox = elementBox.intersected(viewport);
|
||||
QPoint mousePos = boundedBox.center();
|
||||
|
||||
QRect r = QRect(QPoint(left, top), boundedBox.size());
|
||||
QPoint p = r.center();
|
||||
bool ok = QWebElement(element).evaluateJavaScript(QString("Capybara.clickTest(this, %1, %2);").arg(p.x()).arg(p.y())).toBool();
|
||||
|
||||
if (ok) {
|
||||
execClick(mousePos);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
void JavascriptInvocation::execClick(QPoint mousePos) {
|
||||
QMouseEvent event(QEvent::MouseMove, mousePos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||
QApplication::sendEvent(m_page, &event);
|
||||
|
||||
|
|
|
@ -14,11 +14,12 @@ class JavascriptInvocation : public QObject {
|
|||
JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent = 0);
|
||||
QString &functionName();
|
||||
QStringList &arguments();
|
||||
Q_INVOKABLE void click(const QWebElement &element, int left, int top, int width, int height);
|
||||
Q_INVOKABLE bool click(const QWebElement &element, int left, int top, int width, int height);
|
||||
|
||||
private:
|
||||
QString m_functionName;
|
||||
QStringList m_arguments;
|
||||
WebPage *m_page;
|
||||
void execClick(QPoint mousePos);
|
||||
};
|
||||
|
||||
|
|
|
@ -108,11 +108,24 @@ Capybara = {
|
|||
return this.nodes[index].submit();
|
||||
},
|
||||
|
||||
clickTest: function(node, x, y) {
|
||||
var el = document.elementFromPoint(x, y);
|
||||
|
||||
while (el) {
|
||||
if (el === node)
|
||||
return true;
|
||||
else
|
||||
el = el.parentNode;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
click: function (index) {
|
||||
var node = this.nodes[index];
|
||||
node.scrollIntoViewIfNeeded();
|
||||
var rect = node.getClientRects()[0];
|
||||
CapybaraInvocation.click(node, rect.left, rect.top, rect.width, rect.height);
|
||||
return CapybaraInvocation.click(node, rect.left, rect.top, rect.width, rect.height);
|
||||
},
|
||||
|
||||
trigger: function (index, eventName) {
|
||||
|
|
Loading…
Reference in New Issue