mirror of
https://github.com/thoughtbot/capybara-webkit
synced 2023-03-27 23:22:28 -04:00
JavaScript error handling
This commit is contained in:
parent
be6a055687
commit
fe6eff79e6
11 changed files with 83 additions and 27 deletions
|
@ -7,7 +7,7 @@ CurrentUrl::CurrentUrl(WebPageManager *manager, QStringList &arguments, QObject
|
|||
|
||||
void CurrentUrl::start() {
|
||||
QStringList arguments;
|
||||
QVariant result = page()->invokeCapybaraFunction("currentUrl", arguments);
|
||||
QVariant result = page()->currentFrame()->evaluateJavaScript("window.location.toString()");
|
||||
QString url = result.toString();
|
||||
emitFinished(true, url);
|
||||
}
|
||||
|
|
14
src/Find.cpp
14
src/Find.cpp
|
@ -2,19 +2,19 @@
|
|||
#include "SocketCommand.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
#include "InvocationResult.h"
|
||||
|
||||
Find::Find(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
||||
}
|
||||
|
||||
void Find::start() {
|
||||
InvocationResult result = page()->invokeCapybaraFunction("find", arguments());
|
||||
|
||||
if (result.hasError())
|
||||
return emitFinished(false, QString("Invalid XPath expression"));
|
||||
|
||||
QString message;
|
||||
QVariant result = page()->invokeCapybaraFunction("find", arguments());
|
||||
|
||||
if (result.isValid()) {
|
||||
message = result.toString();
|
||||
message = result.result().toString();
|
||||
emitFinished(true, message);
|
||||
} else {
|
||||
emitFinished(false, QString("Invalid XPath expression"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
src/InvocationResult.cpp
Normal file
14
src/InvocationResult.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include "InvocationResult.h"
|
||||
|
||||
InvocationResult::InvocationResult(QVariant result, bool error) {
|
||||
m_result = result;
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
const QVariant &InvocationResult::result() const {
|
||||
return m_result;
|
||||
}
|
||||
|
||||
bool InvocationResult::hasError() {
|
||||
return m_error;
|
||||
}
|
13
src/InvocationResult.h
Normal file
13
src/InvocationResult.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <QVariant>
|
||||
|
||||
class InvocationResult {
|
||||
public:
|
||||
InvocationResult(QVariant result, bool error = false);
|
||||
const QVariant &result() const;
|
||||
bool hasError();
|
||||
|
||||
private:
|
||||
QVariant m_result;
|
||||
bool m_error;
|
||||
};
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "JavascriptInvocation.h"
|
||||
#include "WebPage.h"
|
||||
#include "InvocationResult.h"
|
||||
#include <QApplication>
|
||||
|
||||
JavascriptInvocation::JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent) : QObject(parent) {
|
||||
|
@ -16,6 +17,23 @@ QStringList &JavascriptInvocation::arguments() {
|
|||
return m_arguments;
|
||||
}
|
||||
|
||||
QVariantMap JavascriptInvocation::getError() {
|
||||
return m_error;
|
||||
}
|
||||
|
||||
void JavascriptInvocation::setError(QVariantMap error) {
|
||||
m_error = error;
|
||||
}
|
||||
|
||||
InvocationResult JavascriptInvocation::invoke(QWebFrame *frame) {
|
||||
frame->addToJavaScriptWindowObject("CapybaraInvocation", this);
|
||||
QVariant result = frame->evaluateJavaScript("Capybara.invoke()");
|
||||
if (getError().isEmpty())
|
||||
return InvocationResult(result);
|
||||
else
|
||||
return InvocationResult(getError(), true);
|
||||
}
|
||||
|
||||
bool JavascriptInvocation::click(QWebElement element, int left, int top, int width, int height) {
|
||||
QRect elementBox(left, top, width, height);
|
||||
QRect viewport(QPoint(0, 0), m_page->viewportSize());
|
||||
|
|
|
@ -4,23 +4,28 @@
|
|||
#include <QWebElement>
|
||||
|
||||
class WebPage;
|
||||
class InvocationResult;
|
||||
|
||||
class JavascriptInvocation : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString functionName READ functionName)
|
||||
Q_PROPERTY(QStringList arguments READ arguments)
|
||||
Q_PROPERTY(QVariantMap error READ getError WRITE setError)
|
||||
|
||||
public:
|
||||
JavascriptInvocation(const QString &functionName, const QStringList &arguments, WebPage *page, QObject *parent = 0);
|
||||
QString &functionName();
|
||||
QStringList &arguments();
|
||||
Q_INVOKABLE bool click(QWebElement element, int left, int top, int width, int height);
|
||||
QVariantMap getError();
|
||||
void setError(QVariantMap error);
|
||||
InvocationResult invoke(QWebFrame *);
|
||||
|
||||
private:
|
||||
QString m_functionName;
|
||||
QStringList m_arguments;
|
||||
WebPage *m_page;
|
||||
void execClick(QPoint mousePos);
|
||||
|
||||
QVariantMap m_error;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Node.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
#include "InvocationResult.h"
|
||||
|
||||
Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
||||
}
|
||||
|
@ -8,8 +9,12 @@ Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : S
|
|||
void Node::start() {
|
||||
QStringList functionArguments(arguments());
|
||||
QString functionName = functionArguments.takeFirst();
|
||||
QVariant result = page()->invokeCapybaraFunction(functionName, functionArguments);
|
||||
QString attributeValue = result.toString();
|
||||
InvocationResult result = page()->invokeCapybaraFunction(functionName, functionArguments);
|
||||
|
||||
if (result.hasError())
|
||||
return emitFinished(false);
|
||||
|
||||
QString attributeValue = result.result().toString();
|
||||
emitFinished(true, attributeValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "NetworkAccessManager.h"
|
||||
#include "NetworkCookieJar.h"
|
||||
#include "UnsupportedContentHandler.h"
|
||||
#include "InvocationResult.h"
|
||||
#include <QResource>
|
||||
#include <iostream>
|
||||
#include <QWebSettings>
|
||||
|
@ -117,16 +118,13 @@ bool WebPage::shouldInterruptJavaScript() {
|
|||
return false;
|
||||
}
|
||||
|
||||
QVariant WebPage::invokeCapybaraFunction(const char *name, const QStringList &arguments) {
|
||||
InvocationResult WebPage::invokeCapybaraFunction(const char *name, const QStringList &arguments) {
|
||||
QString qname(name);
|
||||
QString objectName("CapybaraInvocation");
|
||||
JavascriptInvocation invocation(qname, arguments, this);
|
||||
currentFrame()->addToJavaScriptWindowObject(objectName, &invocation);
|
||||
QString javascript = QString("Capybara.invoke()");
|
||||
return currentFrame()->evaluateJavaScript(javascript);
|
||||
return invocation.invoke(currentFrame());
|
||||
}
|
||||
|
||||
QVariant WebPage::invokeCapybaraFunction(QString &name, const QStringList &arguments) {
|
||||
InvocationResult WebPage::invokeCapybaraFunction(QString &name, const QStringList &arguments) {
|
||||
return invokeCapybaraFunction(name.toAscii().data(), arguments);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
|
||||
class WebPageManager;
|
||||
class NetworkAccessManager;
|
||||
class InvocationResult;
|
||||
|
||||
class WebPage : public QWebPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WebPage(WebPageManager *, QObject *parent = 0);
|
||||
QVariant invokeCapybaraFunction(const char *name, const QStringList &arguments);
|
||||
QVariant invokeCapybaraFunction(QString &name, const QStringList &arguments);
|
||||
InvocationResult invokeCapybaraFunction(const char *name, const QStringList &arguments);
|
||||
InvocationResult invokeCapybaraFunction(QString &name, const QStringList &arguments);
|
||||
QString failureString();
|
||||
QString userAgentForUrl(const QUrl &url ) const;
|
||||
void setUserAgent(QString userAgent);
|
||||
|
|
|
@ -4,17 +4,17 @@ Capybara = {
|
|||
attachedFiles: [],
|
||||
|
||||
invoke: function () {
|
||||
try {
|
||||
return this[CapybaraInvocation.functionName].apply(this, CapybaraInvocation.arguments);
|
||||
} catch (e) {
|
||||
CapybaraInvocation.error = e;
|
||||
}
|
||||
},
|
||||
|
||||
find: function (xpath) {
|
||||
return this.findRelativeTo(document, xpath);
|
||||
},
|
||||
|
||||
currentUrl: function () {
|
||||
return window.location.toString();
|
||||
},
|
||||
|
||||
findWithin: function (index, xpath) {
|
||||
return this.findRelativeTo(this.nodes[index], xpath);
|
||||
},
|
||||
|
|
|
@ -56,7 +56,8 @@ HEADERS = \
|
|||
TimeoutCommand.h \
|
||||
SetUrlBlacklist.h \
|
||||
NoOpReply.h \
|
||||
JsonSerializer.h
|
||||
JsonSerializer.h \
|
||||
InvocationResult.h
|
||||
|
||||
SOURCES = \
|
||||
Version.cpp \
|
||||
|
@ -114,7 +115,8 @@ SOURCES = \
|
|||
TimeoutCommand.cpp \
|
||||
SetUrlBlacklist.cpp \
|
||||
NoOpReply.cpp \
|
||||
JsonSerializer.cpp
|
||||
JsonSerializer.cpp \
|
||||
InvocationResult.cpp
|
||||
|
||||
RESOURCES = webkit_server.qrc
|
||||
QT += network webkit
|
||||
|
|
Loading…
Reference in a new issue