Skip to content

Commit

Permalink
JavaScript error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mhoran authored and youpy committed Jul 22, 2014
1 parent 03d9a5a commit 6497404
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/CurrentUrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
16 changes: 8 additions & 8 deletions src/Find.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
QString message;
QVariant result = page()->invokeCapybaraFunction("find", arguments());
InvocationResult result = page()->invokeCapybaraFunction("find", arguments());

if (result.hasError())
return emitFinished(false, QString("Invalid XPath expression"));

if (result.isValid()) {
message = result.toString();
emitFinished(true, message);
} else {
emitFinished(false, QString("Invalid XPath expression"));
}
QString message;
message = result.result().toString();
emitFinished(true, message);
}

14 changes: 14 additions & 0 deletions src/InvocationResult.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 0 deletions src/InvocationResult.h
Original file line number Diff line number Diff line change
@@ -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;
};

18 changes: 18 additions & 0 deletions src/JavascriptInvocation.cpp
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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());
Expand Down
7 changes: 6 additions & 1 deletion src/JavascriptInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

9 changes: 7 additions & 2 deletions src/Node.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
#include "Node.h"
#include "WebPage.h"
#include "WebPageManager.h"
#include "InvocationResult.h"

Node::Node(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
}

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);
}

Expand Down
10 changes: 4 additions & 6 deletions src/WebPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "NetworkAccessManager.h"
#include "NetworkCookieJar.h"
#include "UnsupportedContentHandler.h"
#include "InvocationResult.h"
#include <QResource>
#include <iostream>
#include <QWebSettings>
Expand Down Expand Up @@ -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);
}

Expand Down
5 changes: 3 additions & 2 deletions src/WebPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,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);
Expand Down
10 changes: 5 additions & 5 deletions src/capybara.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ Capybara = {
attachedFiles: [],

invoke: function () {
return this[CapybaraInvocation.functionName].apply(this, CapybaraInvocation.arguments);
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);
},
Expand Down
6 changes: 4 additions & 2 deletions src/webkit_server.pro
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ HEADERS = \
TimeoutCommand.h \
SetUrlBlacklist.h \
NoOpReply.h \
JsonSerializer.h
JsonSerializer.h \
InvocationResult.h

SOURCES = \
Version.cpp \
Expand Down Expand Up @@ -114,7 +115,8 @@ SOURCES = \
TimeoutCommand.cpp \
SetUrlBlacklist.cpp \
NoOpReply.cpp \
JsonSerializer.cpp
JsonSerializer.cpp \
InvocationResult.cpp

RESOURCES = webkit_server.qrc
QT += network webkit
Expand Down

0 comments on commit 6497404

Please sign in to comment.