intentmedia-capybara-webkit 0.7.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Appraisals +7 -0
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +65 -0
- data/LICENSE +19 -0
- data/README.md +67 -0
- data/Rakefile +78 -0
- data/bin/Info.plist +22 -0
- data/capybara-webkit.gemspec +24 -0
- data/extconf.rb +2 -0
- data/gemfiles/1.0.gemfile +7 -0
- data/gemfiles/1.0.gemfile.lock +65 -0
- data/gemfiles/1.1.gemfile +7 -0
- data/gemfiles/1.1.gemfile.lock +65 -0
- data/lib/capybara-webkit.rb +1 -0
- data/lib/capybara/driver/webkit.rb +113 -0
- data/lib/capybara/driver/webkit/browser.rb +216 -0
- data/lib/capybara/driver/webkit/node.rb +118 -0
- data/lib/capybara/driver/webkit/socket_debugger.rb +43 -0
- data/lib/capybara/webkit.rb +11 -0
- data/lib/capybara_webkit_builder.rb +40 -0
- data/spec/browser_spec.rb +178 -0
- data/spec/driver_rendering_spec.rb +80 -0
- data/spec/driver_spec.rb +1048 -0
- data/spec/integration/driver_spec.rb +20 -0
- data/spec/integration/session_spec.rb +137 -0
- data/spec/self_signed_ssl_cert.rb +42 -0
- data/spec/spec_helper.rb +25 -0
- data/src/Body.h +12 -0
- data/src/ClearCookies.cpp +18 -0
- data/src/ClearCookies.h +11 -0
- data/src/Command.cpp +15 -0
- data/src/Command.h +29 -0
- data/src/CommandFactory.cpp +29 -0
- data/src/CommandFactory.h +16 -0
- data/src/CommandParser.cpp +68 -0
- data/src/CommandParser.h +29 -0
- data/src/Connection.cpp +82 -0
- data/src/Connection.h +36 -0
- data/src/Evaluate.cpp +84 -0
- data/src/Evaluate.h +22 -0
- data/src/Execute.cpp +16 -0
- data/src/Execute.h +12 -0
- data/src/Find.cpp +19 -0
- data/src/Find.h +13 -0
- data/src/FrameFocus.cpp +66 -0
- data/src/FrameFocus.h +28 -0
- data/src/GetCookies.cpp +22 -0
- data/src/GetCookies.h +14 -0
- data/src/Header.cpp +18 -0
- data/src/Header.h +11 -0
- data/src/Headers.cpp +11 -0
- data/src/Headers.h +12 -0
- data/src/JavascriptInvocation.cpp +14 -0
- data/src/JavascriptInvocation.h +19 -0
- data/src/NetworkAccessManager.cpp +25 -0
- data/src/NetworkAccessManager.h +18 -0
- data/src/NetworkCookieJar.cpp +101 -0
- data/src/NetworkCookieJar.h +15 -0
- data/src/Node.cpp +14 -0
- data/src/Node.h +13 -0
- data/src/Render.cpp +19 -0
- data/src/Render.h +12 -0
- data/src/Reset.cpp +20 -0
- data/src/Reset.h +12 -0
- data/src/Response.cpp +19 -0
- data/src/Response.h +13 -0
- data/src/Server.cpp +25 -0
- data/src/Server.h +21 -0
- data/src/SetCookie.cpp +18 -0
- data/src/SetCookie.h +11 -0
- data/src/SetProxy.cpp +24 -0
- data/src/SetProxy.h +11 -0
- data/src/Source.cpp +20 -0
- data/src/Source.h +19 -0
- data/src/Status.cpp +13 -0
- data/src/Status.h +12 -0
- data/src/UnsupportedContentHandler.cpp +32 -0
- data/src/UnsupportedContentHandler.h +18 -0
- data/src/Url.cpp +15 -0
- data/src/Url.h +12 -0
- data/src/Visit.cpp +21 -0
- data/src/Visit.h +15 -0
- data/src/WebPage.cpp +226 -0
- data/src/WebPage.h +54 -0
- data/src/body.cpp +11 -0
- data/src/capybara.js +205 -0
- data/src/find_command.h +24 -0
- data/src/main.cpp +34 -0
- data/src/webkit_server.pro +71 -0
- data/src/webkit_server.qrc +5 -0
- data/templates/Command.cpp +10 -0
- data/templates/Command.h +12 -0
- data/webkit_server.pro +4 -0
- metadata +246 -0
data/src/Header.h
ADDED
data/src/Headers.cpp
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#include "Headers.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
Headers::Headers(WebPage *page, QObject *parent) : Command(page, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void Headers::start(QStringList &arguments) {
|
8
|
+
Q_UNUSED(arguments);
|
9
|
+
emit finished(new Response(true, page()->pageHeaders()));
|
10
|
+
}
|
11
|
+
|
data/src/Headers.h
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "JavascriptInvocation.h"
|
2
|
+
|
3
|
+
JavascriptInvocation::JavascriptInvocation(QString &functionName, QStringList &arguments, QObject *parent) : QObject(parent) {
|
4
|
+
m_functionName = functionName;
|
5
|
+
m_arguments = arguments;
|
6
|
+
}
|
7
|
+
|
8
|
+
QString &JavascriptInvocation::functionName() {
|
9
|
+
return m_functionName;
|
10
|
+
}
|
11
|
+
|
12
|
+
QStringList &JavascriptInvocation::arguments() {
|
13
|
+
return m_arguments;
|
14
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#include <QObject>
|
2
|
+
#include <QString>
|
3
|
+
#include <QStringList>
|
4
|
+
|
5
|
+
class JavascriptInvocation : public QObject {
|
6
|
+
Q_OBJECT
|
7
|
+
Q_PROPERTY(QString functionName READ functionName)
|
8
|
+
Q_PROPERTY(QStringList arguments READ arguments)
|
9
|
+
|
10
|
+
public:
|
11
|
+
JavascriptInvocation(QString &functionName, QStringList &arguments, QObject *parent = 0);
|
12
|
+
QString &functionName();
|
13
|
+
QStringList &arguments();
|
14
|
+
|
15
|
+
private:
|
16
|
+
QString m_functionName;
|
17
|
+
QStringList m_arguments;
|
18
|
+
};
|
19
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#include "NetworkAccessManager.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include <iostream>
|
4
|
+
|
5
|
+
|
6
|
+
NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) {
|
7
|
+
}
|
8
|
+
|
9
|
+
QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) {
|
10
|
+
QNetworkRequest new_request(request);
|
11
|
+
if (operation != QNetworkAccessManager::PostOperation && operation != QNetworkAccessManager::PutOperation) {
|
12
|
+
new_request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant());
|
13
|
+
}
|
14
|
+
QHashIterator<QString, QString> item(m_headers);
|
15
|
+
while (item.hasNext()) {
|
16
|
+
item.next();
|
17
|
+
new_request.setRawHeader(item.key().toAscii(), item.value().toAscii());
|
18
|
+
}
|
19
|
+
return QNetworkAccessManager::createRequest(operation, new_request, outgoingData);
|
20
|
+
};
|
21
|
+
|
22
|
+
void NetworkAccessManager::addHeader(QString key, QString value) {
|
23
|
+
m_headers.insert(key, value);
|
24
|
+
};
|
25
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#include <QtNetwork/QNetworkAccessManager>
|
2
|
+
#include <QtNetwork/QNetworkRequest>
|
3
|
+
#include <QtNetwork/QNetworkReply>
|
4
|
+
|
5
|
+
class NetworkAccessManager : public QNetworkAccessManager {
|
6
|
+
|
7
|
+
Q_OBJECT
|
8
|
+
|
9
|
+
public:
|
10
|
+
NetworkAccessManager(QObject *parent = 0);
|
11
|
+
void addHeader(QString key, QString value);
|
12
|
+
|
13
|
+
protected:
|
14
|
+
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
|
15
|
+
|
16
|
+
private:
|
17
|
+
QHash<QString, QString> m_headers;
|
18
|
+
};
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#include "NetworkCookieJar.h"
|
2
|
+
#include "QtCore/qdatetime.h"
|
3
|
+
|
4
|
+
NetworkCookieJar::NetworkCookieJar(QObject *parent)
|
5
|
+
: QNetworkCookieJar(parent)
|
6
|
+
{ }
|
7
|
+
|
8
|
+
QList<QNetworkCookie> NetworkCookieJar::getAllCookies() const
|
9
|
+
{
|
10
|
+
return allCookies();
|
11
|
+
}
|
12
|
+
|
13
|
+
void NetworkCookieJar::clearCookies()
|
14
|
+
{
|
15
|
+
setAllCookies(QList<QNetworkCookie>());
|
16
|
+
}
|
17
|
+
|
18
|
+
static inline bool isParentDomain(QString domain, QString reference)
|
19
|
+
{
|
20
|
+
if (!reference.startsWith(QLatin1Char('.')))
|
21
|
+
return domain == reference;
|
22
|
+
|
23
|
+
return domain.endsWith(reference) || domain == reference.mid(1);
|
24
|
+
}
|
25
|
+
|
26
|
+
void NetworkCookieJar::overwriteCookies(const QList<QNetworkCookie>& cookieList)
|
27
|
+
{
|
28
|
+
/* this function is basically a copy-and-paste of the original
|
29
|
+
QNetworkCookieJar::setCookiesFromUrl with the domain and
|
30
|
+
path validations removed */
|
31
|
+
|
32
|
+
QString defaultPath(QLatin1Char('/'));
|
33
|
+
QDateTime now = QDateTime::currentDateTime();
|
34
|
+
QList<QNetworkCookie> newCookies = allCookies();
|
35
|
+
|
36
|
+
foreach (QNetworkCookie cookie, cookieList) {
|
37
|
+
bool isDeletion = (!cookie.isSessionCookie() &&
|
38
|
+
cookie.expirationDate() < now);
|
39
|
+
|
40
|
+
// validate the cookie & set the defaults if unset
|
41
|
+
if (cookie.path().isEmpty())
|
42
|
+
cookie.setPath(defaultPath);
|
43
|
+
|
44
|
+
// don't do path checking. See http://bugreports.qt.nokia.com/browse/QTBUG-5815
|
45
|
+
// else if (!isParentPath(pathAndFileName, cookie.path())) {
|
46
|
+
// continue; // not accepted
|
47
|
+
// }
|
48
|
+
|
49
|
+
if (cookie.domain().isEmpty()) {
|
50
|
+
continue;
|
51
|
+
} else {
|
52
|
+
// Ensure the domain starts with a dot if its field was not empty
|
53
|
+
// in the HTTP header. There are some servers that forget the
|
54
|
+
// leading dot and this is actually forbidden according to RFC 2109,
|
55
|
+
// but all browsers accept it anyway so we do that as well.
|
56
|
+
if (!cookie.domain().startsWith(QLatin1Char('.')))
|
57
|
+
cookie.setDomain(QLatin1Char('.') + cookie.domain());
|
58
|
+
|
59
|
+
QString domain = cookie.domain();
|
60
|
+
|
61
|
+
// the check for effective TLDs makes the "embedded dot" rule from RFC 2109 section 4.3.2
|
62
|
+
// redundant; the "leading dot" rule has been relaxed anyway, see above
|
63
|
+
// we remove the leading dot for this check
|
64
|
+
/*
|
65
|
+
if (QNetworkCookieJarPrivate::isEffectiveTLD(domain.remove(0, 1)))
|
66
|
+
continue; // not accepted
|
67
|
+
*/
|
68
|
+
}
|
69
|
+
|
70
|
+
for (int i = 0; i < newCookies.size(); ++i) {
|
71
|
+
// does this cookie already exist?
|
72
|
+
const QNetworkCookie ¤t = newCookies.at(i);
|
73
|
+
if (cookie.name() == current.name() &&
|
74
|
+
cookie.domain() == current.domain() &&
|
75
|
+
cookie.path() == current.path()) {
|
76
|
+
// found a match
|
77
|
+
newCookies.removeAt(i);
|
78
|
+
break;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
// did not find a match
|
83
|
+
if (!isDeletion) {
|
84
|
+
int countForDomain = 0;
|
85
|
+
for (int i = newCookies.size() - 1; i >= 0; --i) {
|
86
|
+
// Start from the end and delete the oldest cookies to keep a maximum count of 50.
|
87
|
+
const QNetworkCookie ¤t = newCookies.at(i);
|
88
|
+
if (isParentDomain(cookie.domain(), current.domain())
|
89
|
+
|| isParentDomain(current.domain(), cookie.domain())) {
|
90
|
+
if (countForDomain >= 49)
|
91
|
+
newCookies.removeAt(i);
|
92
|
+
else
|
93
|
+
++countForDomain;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
newCookies += cookie;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
setAllCookies(newCookies);
|
101
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#include <QtNetwork/QNetworkCookieJar>
|
2
|
+
#include <QtNetwork/QNetworkCookie>
|
3
|
+
|
4
|
+
class NetworkCookieJar : public QNetworkCookieJar {
|
5
|
+
|
6
|
+
Q_OBJECT;
|
7
|
+
|
8
|
+
public:
|
9
|
+
|
10
|
+
NetworkCookieJar(QObject *parent = 0);
|
11
|
+
|
12
|
+
QList<QNetworkCookie> getAllCookies() const;
|
13
|
+
void clearCookies();
|
14
|
+
void overwriteCookies(const QList<QNetworkCookie>& cookieList);
|
15
|
+
};
|
data/src/Node.cpp
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#include "Node.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
Node::Node(WebPage *page, QObject *parent) : Command(page, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void Node::start(QStringList &arguments) {
|
8
|
+
QStringList functionArguments(arguments);
|
9
|
+
QString functionName = functionArguments.takeFirst();
|
10
|
+
QVariant result = page()->invokeCapybaraFunction(functionName, functionArguments);
|
11
|
+
QString attributeValue = result.toString();
|
12
|
+
emit finished(new Response(true, attributeValue));
|
13
|
+
}
|
14
|
+
|
data/src/Node.h
ADDED
data/src/Render.cpp
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "Render.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
Render::Render(WebPage *page, QObject *parent) : Command(page, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void Render::start(QStringList &arguments) {
|
8
|
+
QStringList functionArguments(arguments);
|
9
|
+
QString imagePath = functionArguments.takeFirst();
|
10
|
+
int width = functionArguments.takeFirst().toInt();
|
11
|
+
int height = functionArguments.takeFirst().toInt();
|
12
|
+
|
13
|
+
QSize size(width, height);
|
14
|
+
page()->setViewportSize(size);
|
15
|
+
|
16
|
+
bool result = page()->render( imagePath );
|
17
|
+
|
18
|
+
emit finished(new Response(result));
|
19
|
+
}
|
data/src/Render.h
ADDED
data/src/Reset.cpp
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#include "Reset.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "NetworkAccessManager.h"
|
4
|
+
#include "NetworkCookieJar.h"
|
5
|
+
|
6
|
+
Reset::Reset(WebPage *page, QObject *parent) : Command(page, parent) {
|
7
|
+
}
|
8
|
+
|
9
|
+
void Reset::start(QStringList &arguments) {
|
10
|
+
Q_UNUSED(arguments);
|
11
|
+
|
12
|
+
page()->triggerAction(QWebPage::Stop);
|
13
|
+
page()->currentFrame()->setHtml("<html><body></body></html>");
|
14
|
+
page()->networkAccessManager()->setCookieJar(new NetworkCookieJar());
|
15
|
+
page()->setCustomNetworkAccessManager();
|
16
|
+
page()->setUserAgent(NULL);
|
17
|
+
page()->resetResponseHeaders();
|
18
|
+
emit finished(new Response(true));
|
19
|
+
}
|
20
|
+
|
data/src/Reset.h
ADDED
data/src/Response.cpp
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#include "Response.h"
|
2
|
+
#include <iostream>
|
3
|
+
|
4
|
+
Response::Response(bool success, QString message) {
|
5
|
+
m_success = success;
|
6
|
+
m_message = message;
|
7
|
+
}
|
8
|
+
|
9
|
+
Response::Response(bool success) {
|
10
|
+
m_success = success;
|
11
|
+
}
|
12
|
+
|
13
|
+
bool Response::isSuccess() const {
|
14
|
+
return m_success;
|
15
|
+
}
|
16
|
+
|
17
|
+
QString Response::message() const {
|
18
|
+
return m_message;
|
19
|
+
}
|
data/src/Response.h
ADDED
data/src/Server.cpp
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#include "Server.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "Connection.h"
|
4
|
+
|
5
|
+
#include <QTcpServer>
|
6
|
+
|
7
|
+
Server::Server(QObject *parent, bool ignoreSslErrors) : QObject(parent) {
|
8
|
+
m_tcp_server = new QTcpServer(this);
|
9
|
+
m_page = new WebPage(this);
|
10
|
+
m_page->setIgnoreSslErrors(ignoreSslErrors);
|
11
|
+
}
|
12
|
+
|
13
|
+
bool Server::start() {
|
14
|
+
connect(m_tcp_server, SIGNAL(newConnection()), this, SLOT(handleConnection()));
|
15
|
+
return m_tcp_server->listen(QHostAddress::Any, 0);
|
16
|
+
}
|
17
|
+
|
18
|
+
quint16 Server::server_port() const {
|
19
|
+
return m_tcp_server->serverPort();
|
20
|
+
}
|
21
|
+
|
22
|
+
void Server::handleConnection() {
|
23
|
+
QTcpSocket *socket = m_tcp_server->nextPendingConnection();
|
24
|
+
new Connection(socket, m_page, this);
|
25
|
+
}
|
data/src/Server.h
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#include <QObject>
|
2
|
+
|
3
|
+
class QTcpServer;
|
4
|
+
class WebPage;
|
5
|
+
|
6
|
+
class Server : public QObject {
|
7
|
+
Q_OBJECT
|
8
|
+
|
9
|
+
public:
|
10
|
+
Server(QObject *parent, bool ignoreSslErrors);
|
11
|
+
bool start();
|
12
|
+
quint16 server_port() const;
|
13
|
+
|
14
|
+
public slots:
|
15
|
+
void handleConnection();
|
16
|
+
|
17
|
+
private:
|
18
|
+
QTcpServer *m_tcp_server;
|
19
|
+
WebPage *m_page;
|
20
|
+
};
|
21
|
+
|
data/src/SetCookie.cpp
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#include "SetCookie.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
#include "NetworkCookieJar.h"
|
4
|
+
#include <QNetworkCookie>
|
5
|
+
|
6
|
+
SetCookie::SetCookie(WebPage *page, QObject *parent)
|
7
|
+
: Command(page, parent)
|
8
|
+
{ }
|
9
|
+
|
10
|
+
void SetCookie::start(QStringList &arguments)
|
11
|
+
{
|
12
|
+
QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(arguments[0].toAscii());
|
13
|
+
NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
|
14
|
+
->networkAccessManager()
|
15
|
+
->cookieJar());
|
16
|
+
jar->overwriteCookies(cookies);
|
17
|
+
emit finished(new Response(true));
|
18
|
+
}
|