capybara-webkit 0.7.2 → 0.8.0
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/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -6
- data/Gemfile.lock +15 -13
- data/README.md +9 -8
- data/Rakefile +3 -21
- data/capybara-webkit.gemspec +21 -18
- data/gemfiles/1.0.gemfile.lock +18 -13
- data/gemfiles/1.1.gemfile.lock +18 -13
- data/lib/capybara/driver/webkit.rb +20 -1
- data/lib/capybara/driver/webkit/browser.rb +49 -5
- data/lib/capybara/driver/webkit/cookie_jar.rb +55 -0
- data/lib/capybara/driver/webkit/node.rb +5 -1
- data/lib/capybara/driver/webkit/version.rb +7 -0
- data/lib/capybara/webkit/matchers.rb +39 -0
- data/lib/capybara_webkit_builder.rb +2 -1
- data/spec/browser_spec.rb +150 -2
- data/spec/cookie_jar_spec.rb +48 -0
- data/spec/driver_spec.rb +248 -16
- data/spec/self_signed_ssl_cert.rb +42 -0
- data/src/CommandFactory.cpp +31 -0
- data/src/CommandFactory.h +16 -0
- data/src/CommandParser.cpp +68 -0
- data/src/CommandParser.h +29 -0
- data/src/Connection.cpp +14 -83
- data/src/Connection.h +5 -8
- data/src/ConsoleMessages.cpp +11 -0
- data/src/ConsoleMessages.h +12 -0
- data/src/RequestedUrl.cpp +15 -0
- data/src/RequestedUrl.h +12 -0
- data/src/Reset.cpp +1 -0
- data/src/Server.cpp +2 -1
- data/src/Server.h +1 -1
- data/src/SetProxy.cpp +24 -0
- data/src/SetProxy.h +11 -0
- data/src/UnsupportedContentHandler.cpp +1 -0
- data/src/Visit.cpp +1 -1
- data/src/WebPage.cpp +28 -2
- data/src/WebPage.h +7 -0
- data/src/capybara.js +54 -11
- data/src/find_command.h +4 -0
- data/src/main.cpp +4 -1
- data/src/webkit_server.pro +10 -0
- metadata +67 -47
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
3
|
+
pem = <<-PEM_ENCODED
|
4
|
+
-----BEGIN PRIVATE KEY-----
|
5
|
+
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKW+grT6YW3gv79y
|
6
|
+
P9JkQDtm3cDSUhAhd/TEyRBt/pSKz3pNSygsleBJl2d7g8k0fteec95a7YnYRKGH
|
7
|
+
XhIpUOvl/3uaV2NVipqxwB+Z+0M+7HegxL3e4unaRFy9kf9/UXJzmuA9BTMLrm/w
|
8
|
+
IoW17f+dz7BIFZhCvRurkrmvzraNAgMBAAECgYBv4uB3bYJx20N16Jk+3OAjeXh/
|
9
|
+
Hzu4me9Rc7pLdgVinyYaaK0wrJBsfSFRASdgnyh1RAjx9K3f3PfPlwMg/XUbA6Yd
|
10
|
+
YOYlMnBUwCJX09TH8RFFCzJzbBylpk/sTF1geICln2O2BloT2cM24PlEPvyz1xLa
|
11
|
+
XvxCOnJJfgNU1K6kvQJBANcEVyOMJ9RBfI8gj1o7S70J9yJRI4jvqxuvcOxJBCi6
|
12
|
+
CDatkh/getHswsE3sLj25VhrNsi6UQcN8Bjm8Yjt8BsCQQDFVe0uCwobseprMOuW
|
13
|
+
dPU4+saN1cFnIT5Gp0iwYRPinjUlkh6H/AuUtUulKFXVmxk1KElpp1E3bxpCDgCp
|
14
|
+
oe53AkArO1Mt8Ys8kSIzQO+xy8RRsQRAoSHM8atsuJyy1YeBjM4D+GguApuPQ9Rw
|
15
|
+
tvrQZcv9OCleuJ98FKBW0XB1AKpLAkEAmOR3bJofDdAuWTjA/4TEzo32MsRwIZBv
|
16
|
+
KNzJg+bjOkzrzp1EzIVrD5/b6S20O1j9EeOR5as+UN3jEVS6DLQrBwJAe5OTrDiQ
|
17
|
+
vKtUaAwquC4f4Ia05KwJw+vFrPVaOqgc4QLdxRwx4PfV/Uw3OOqMolpPAvpUi9JI
|
18
|
+
LAwIaTtCvo18OQ==
|
19
|
+
-----END PRIVATE KEY-----
|
20
|
+
-----BEGIN CERTIFICATE-----
|
21
|
+
MIICgDCCAemgAwIBAgIJANWcyeZB2ql1MA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
|
22
|
+
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
23
|
+
aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xMTA5MjgyMDIx
|
24
|
+
MTFaFw0xMjA5MjcyMDIxMTFaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21l
|
25
|
+
LVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV
|
26
|
+
BAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApb6CtPph
|
27
|
+
beC/v3I/0mRAO2bdwNJSECF39MTJEG3+lIrPek1LKCyV4EmXZ3uDyTR+155z3lrt
|
28
|
+
idhEoYdeEilQ6+X/e5pXY1WKmrHAH5n7Qz7sd6DEvd7i6dpEXL2R/39RcnOa4D0F
|
29
|
+
Mwuub/AihbXt/53PsEgVmEK9G6uSua/Oto0CAwEAAaNQME4wHQYDVR0OBBYEFBAm
|
30
|
+
x19zpY8M8FEcMXB4WQeUhqIiMB8GA1UdIwQYMBaAFBAmx19zpY8M8FEcMXB4WQeU
|
31
|
+
hqIiMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAcznCusWS5Ws77IUl
|
32
|
+
b87vdfCPVphICyfGHGWhHp3BZ3WLOphauAMdOYIiJGtPExyWr4DYpzbvx0+Ljg7G
|
33
|
+
2FNaI0QRXqbR5ccpvwm6KELmU0XDhykNaXiXSdnvIanr3z/hZ5e03mXAywo+nGQj
|
34
|
+
UYTVCb6g/uHVNzXq1NgHGuqogKY=
|
35
|
+
-----END CERTIFICATE-----
|
36
|
+
PEM_ENCODED
|
37
|
+
|
38
|
+
key = OpenSSL::PKey::RSA.new(pem)
|
39
|
+
cert = OpenSSL::X509::Certificate.new(pem)
|
40
|
+
$openssl_self_signed_ctx = OpenSSL::SSL::SSLContext.new
|
41
|
+
$openssl_self_signed_ctx.key = key
|
42
|
+
$openssl_self_signed_ctx.cert = cert
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#include "CommandFactory.h"
|
2
|
+
#include "Visit.h"
|
3
|
+
#include "Find.h"
|
4
|
+
#include "Command.h"
|
5
|
+
#include "Reset.h"
|
6
|
+
#include "Node.h"
|
7
|
+
#include "Url.h"
|
8
|
+
#include "Source.h"
|
9
|
+
#include "Evaluate.h"
|
10
|
+
#include "Execute.h"
|
11
|
+
#include "FrameFocus.h"
|
12
|
+
#include "Header.h"
|
13
|
+
#include "Render.h"
|
14
|
+
#include "Body.h"
|
15
|
+
#include "Status.h"
|
16
|
+
#include "Headers.h"
|
17
|
+
#include "SetCookie.h"
|
18
|
+
#include "ClearCookies.h"
|
19
|
+
#include "GetCookies.h"
|
20
|
+
#include "SetProxy.h"
|
21
|
+
#include "ConsoleMessages.h"
|
22
|
+
#include "RequestedUrl.h"
|
23
|
+
|
24
|
+
CommandFactory::CommandFactory(WebPage *page, QObject *parent) : QObject(parent) {
|
25
|
+
m_page = page;
|
26
|
+
}
|
27
|
+
|
28
|
+
Command *CommandFactory::createCommand(const char *name) {
|
29
|
+
#include "find_command.h"
|
30
|
+
return NULL;
|
31
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#include <QObject>
|
2
|
+
|
3
|
+
class Command;
|
4
|
+
class WebPage;
|
5
|
+
|
6
|
+
class CommandFactory : public QObject {
|
7
|
+
Q_OBJECT
|
8
|
+
|
9
|
+
public:
|
10
|
+
CommandFactory(WebPage *page, QObject *parent = 0);
|
11
|
+
Command *createCommand(const char *name);
|
12
|
+
|
13
|
+
private:
|
14
|
+
WebPage *m_page;
|
15
|
+
};
|
16
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#include "CommandParser.h"
|
2
|
+
|
3
|
+
#include <QIODevice>
|
4
|
+
|
5
|
+
CommandParser::CommandParser(QIODevice *device, QObject *parent) :
|
6
|
+
QObject(parent) {
|
7
|
+
m_device = device;
|
8
|
+
m_expectingDataSize = -1;
|
9
|
+
connect(m_device, SIGNAL(readyRead()), this, SLOT(checkNext()));
|
10
|
+
}
|
11
|
+
|
12
|
+
void CommandParser::checkNext() {
|
13
|
+
if (m_expectingDataSize == -1) {
|
14
|
+
if (m_device->canReadLine()) {
|
15
|
+
readLine();
|
16
|
+
checkNext();
|
17
|
+
}
|
18
|
+
} else {
|
19
|
+
if (m_device->bytesAvailable() >= m_expectingDataSize) {
|
20
|
+
readDataBlock();
|
21
|
+
checkNext();
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
void CommandParser::readLine() {
|
27
|
+
char buffer[128];
|
28
|
+
qint64 lineLength = m_device->readLine(buffer, 128);
|
29
|
+
if (lineLength != -1) {
|
30
|
+
buffer[lineLength - 1] = 0;
|
31
|
+
processNext(buffer);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
void CommandParser::readDataBlock() {
|
36
|
+
char *buffer = new char[m_expectingDataSize + 1];
|
37
|
+
m_device->read(buffer, m_expectingDataSize);
|
38
|
+
buffer[m_expectingDataSize] = 0;
|
39
|
+
processNext(buffer);
|
40
|
+
m_expectingDataSize = -1;
|
41
|
+
delete[] buffer;
|
42
|
+
}
|
43
|
+
|
44
|
+
void CommandParser::processNext(const char *data) {
|
45
|
+
if (m_commandName.isNull()) {
|
46
|
+
m_commandName = data;
|
47
|
+
m_argumentsExpected = -1;
|
48
|
+
} else {
|
49
|
+
processArgument(data);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
void CommandParser::processArgument(const char *data) {
|
54
|
+
if (m_argumentsExpected == -1) {
|
55
|
+
m_argumentsExpected = QString(data).toInt();
|
56
|
+
} else if (m_expectingDataSize == -1) {
|
57
|
+
m_expectingDataSize = QString(data).toInt();
|
58
|
+
} else {
|
59
|
+
m_arguments.append(QString::fromUtf8(data));
|
60
|
+
}
|
61
|
+
|
62
|
+
if (m_arguments.length() == m_argumentsExpected) {
|
63
|
+
emit commandReady(m_commandName, m_arguments);
|
64
|
+
m_commandName = QString();
|
65
|
+
m_arguments.clear();
|
66
|
+
m_argumentsExpected = -1;
|
67
|
+
}
|
68
|
+
}
|
data/src/CommandParser.h
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#include <QObject>
|
2
|
+
#include <QStringList>
|
3
|
+
|
4
|
+
class QIODevice;
|
5
|
+
|
6
|
+
class CommandParser : public QObject {
|
7
|
+
Q_OBJECT
|
8
|
+
|
9
|
+
public:
|
10
|
+
CommandParser(QIODevice *device, QObject *parent = 0);
|
11
|
+
|
12
|
+
public slots:
|
13
|
+
void checkNext();
|
14
|
+
|
15
|
+
signals:
|
16
|
+
void commandReady(QString commandName, QStringList arguments);
|
17
|
+
|
18
|
+
private:
|
19
|
+
void readLine();
|
20
|
+
void readDataBlock();
|
21
|
+
void processNext(const char *line);
|
22
|
+
void processArgument(const char *data);
|
23
|
+
QIODevice *m_device;
|
24
|
+
QString m_commandName;
|
25
|
+
QStringList m_arguments;
|
26
|
+
int m_argumentsExpected;
|
27
|
+
int m_expectingDataSize;
|
28
|
+
};
|
29
|
+
|
data/src/Connection.cpp
CHANGED
@@ -1,24 +1,9 @@
|
|
1
1
|
#include "Connection.h"
|
2
2
|
#include "WebPage.h"
|
3
3
|
#include "UnsupportedContentHandler.h"
|
4
|
-
#include "
|
5
|
-
#include "
|
4
|
+
#include "CommandParser.h"
|
5
|
+
#include "CommandFactory.h"
|
6
6
|
#include "Command.h"
|
7
|
-
#include "Reset.h"
|
8
|
-
#include "Node.h"
|
9
|
-
#include "Url.h"
|
10
|
-
#include "Source.h"
|
11
|
-
#include "Evaluate.h"
|
12
|
-
#include "Execute.h"
|
13
|
-
#include "FrameFocus.h"
|
14
|
-
#include "Header.h"
|
15
|
-
#include "Render.h"
|
16
|
-
#include "Body.h"
|
17
|
-
#include "Status.h"
|
18
|
-
#include "Headers.h"
|
19
|
-
#include "SetCookie.h"
|
20
|
-
#include "ClearCookies.h"
|
21
|
-
#include "GetCookies.h"
|
22
7
|
|
23
8
|
#include <QTcpSocket>
|
24
9
|
#include <iostream>
|
@@ -27,76 +12,31 @@ Connection::Connection(QTcpSocket *socket, WebPage *page, QObject *parent) :
|
|
27
12
|
QObject(parent) {
|
28
13
|
m_socket = socket;
|
29
14
|
m_page = page;
|
15
|
+
m_commandParser = new CommandParser(socket, this);
|
16
|
+
m_commandFactory = new CommandFactory(page, this);
|
30
17
|
m_command = NULL;
|
31
|
-
m_expectingDataSize = -1;
|
32
18
|
m_pageSuccess = true;
|
33
19
|
m_commandWaiting = false;
|
34
|
-
connect(m_socket, SIGNAL(readyRead()),
|
20
|
+
connect(m_socket, SIGNAL(readyRead()), m_commandParser, SLOT(checkNext()));
|
21
|
+
connect(m_commandParser, SIGNAL(commandReady(QString, QStringList)), this, SLOT(commandReady(QString, QStringList)));
|
35
22
|
connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
|
36
23
|
}
|
37
24
|
|
38
|
-
void Connection::checkNext() {
|
39
|
-
if (m_expectingDataSize == -1) {
|
40
|
-
if (m_socket->canReadLine()) {
|
41
|
-
readLine();
|
42
|
-
checkNext();
|
43
|
-
}
|
44
|
-
} else {
|
45
|
-
if (m_socket->bytesAvailable() >= m_expectingDataSize) {
|
46
|
-
readDataBlock();
|
47
|
-
checkNext();
|
48
|
-
}
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
void Connection::readLine() {
|
53
|
-
char buffer[128];
|
54
|
-
qint64 lineLength = m_socket->readLine(buffer, 128);
|
55
|
-
if (lineLength != -1) {
|
56
|
-
buffer[lineLength - 1] = 0;
|
57
|
-
processNext(buffer);
|
58
|
-
}
|
59
|
-
}
|
60
|
-
|
61
|
-
void Connection::readDataBlock() {
|
62
|
-
char *buffer = new char[m_expectingDataSize + 1];
|
63
|
-
m_socket->read(buffer, m_expectingDataSize);
|
64
|
-
buffer[m_expectingDataSize] = 0;
|
65
|
-
processNext(buffer);
|
66
|
-
m_expectingDataSize = -1;
|
67
|
-
delete[] buffer;
|
68
|
-
}
|
69
|
-
|
70
|
-
void Connection::processNext(const char *data) {
|
71
|
-
if (m_commandName.isNull()) {
|
72
|
-
m_commandName = data;
|
73
|
-
m_argumentsExpected = -1;
|
74
|
-
} else {
|
75
|
-
processArgument(data);
|
76
|
-
}
|
77
|
-
}
|
78
25
|
|
79
|
-
void Connection::
|
80
|
-
|
81
|
-
|
82
|
-
} else if (m_expectingDataSize == -1) {
|
83
|
-
m_expectingDataSize = QString(data).toInt();
|
84
|
-
} else {
|
85
|
-
m_arguments.append(QString::fromUtf8(data));
|
86
|
-
}
|
26
|
+
void Connection::commandReady(QString commandName, QStringList arguments) {
|
27
|
+
m_commandName = commandName;
|
28
|
+
m_arguments = arguments;
|
87
29
|
|
88
|
-
if (
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
startCommand();
|
93
|
-
}
|
30
|
+
if (m_page->isLoading())
|
31
|
+
m_commandWaiting = true;
|
32
|
+
else
|
33
|
+
startCommand();
|
94
34
|
}
|
95
35
|
|
96
36
|
void Connection::startCommand() {
|
97
37
|
m_commandWaiting = false;
|
98
38
|
if (m_pageSuccess) {
|
99
|
-
m_command = createCommand(m_commandName.toAscii().constData());
|
39
|
+
m_command = m_commandFactory->createCommand(m_commandName.toAscii().constData());
|
100
40
|
if (m_command) {
|
101
41
|
connect(m_command,
|
102
42
|
SIGNAL(finished(Response *)),
|
@@ -115,11 +55,6 @@ void Connection::startCommand() {
|
|
115
55
|
}
|
116
56
|
}
|
117
57
|
|
118
|
-
Command *Connection::createCommand(const char *name) {
|
119
|
-
#include "find_command.h"
|
120
|
-
return NULL;
|
121
|
-
}
|
122
|
-
|
123
58
|
void Connection::pendingLoadFinished(bool success) {
|
124
59
|
m_pageSuccess = success;
|
125
60
|
if (m_commandWaiting)
|
@@ -143,9 +78,5 @@ void Connection::writeResponse(Response *response) {
|
|
143
78
|
m_socket->write(messageLength.toAscii());
|
144
79
|
m_socket->write(messageUtf8);
|
145
80
|
delete response;
|
146
|
-
|
147
|
-
m_arguments.clear();
|
148
|
-
m_commandName = QString();
|
149
|
-
m_argumentsExpected = -1;
|
150
81
|
}
|
151
82
|
|
data/src/Connection.h
CHANGED
@@ -5,6 +5,8 @@ class QTcpSocket;
|
|
5
5
|
class WebPage;
|
6
6
|
class Command;
|
7
7
|
class Response;
|
8
|
+
class CommandParser;
|
9
|
+
class CommandFactory;
|
8
10
|
|
9
11
|
class Connection : public QObject {
|
10
12
|
Q_OBJECT
|
@@ -13,16 +15,11 @@ class Connection : public QObject {
|
|
13
15
|
Connection(QTcpSocket *socket, WebPage *page, QObject *parent = 0);
|
14
16
|
|
15
17
|
public slots:
|
16
|
-
void
|
18
|
+
void commandReady(QString commandName, QStringList arguments);
|
17
19
|
void finishCommand(Response *response);
|
18
20
|
void pendingLoadFinished(bool success);
|
19
21
|
|
20
22
|
private:
|
21
|
-
void readLine();
|
22
|
-
void readDataBlock();
|
23
|
-
void processNext(const char *line);
|
24
|
-
Command *createCommand(const char *name);
|
25
|
-
void processArgument(const char *line);
|
26
23
|
void startCommand();
|
27
24
|
void writeResponse(Response *response);
|
28
25
|
|
@@ -30,9 +27,9 @@ class Connection : public QObject {
|
|
30
27
|
QString m_commandName;
|
31
28
|
Command *m_command;
|
32
29
|
QStringList m_arguments;
|
33
|
-
int m_argumentsExpected;
|
34
30
|
WebPage *m_page;
|
35
|
-
|
31
|
+
CommandParser *m_commandParser;
|
32
|
+
CommandFactory *m_commandFactory;
|
36
33
|
bool m_pageSuccess;
|
37
34
|
bool m_commandWaiting;
|
38
35
|
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#include "ConsoleMessages.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
ConsoleMessages::ConsoleMessages(WebPage *page, QObject *parent) : Command(page, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void ConsoleMessages::start(QStringList &arguments) {
|
8
|
+
Q_UNUSED(arguments);
|
9
|
+
emit finished(new Response(true, page()->consoleMessages()));
|
10
|
+
}
|
11
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#include "RequestedUrl.h"
|
2
|
+
#include "WebPage.h"
|
3
|
+
|
4
|
+
RequestedUrl::RequestedUrl(WebPage *page, QObject *parent) : Command(page, parent) {
|
5
|
+
}
|
6
|
+
|
7
|
+
void RequestedUrl::start(QStringList &arguments) {
|
8
|
+
Q_UNUSED(arguments);
|
9
|
+
|
10
|
+
QUrl humanUrl = page()->currentFrame()->requestedUrl();
|
11
|
+
QByteArray encodedBytes = humanUrl.toEncoded();
|
12
|
+
QString urlString = QString(encodedBytes);
|
13
|
+
emit finished(new Response(true, urlString));
|
14
|
+
}
|
15
|
+
|
data/src/RequestedUrl.h
ADDED
data/src/Reset.cpp
CHANGED
data/src/Server.cpp
CHANGED
@@ -4,9 +4,10 @@
|
|
4
4
|
|
5
5
|
#include <QTcpServer>
|
6
6
|
|
7
|
-
Server::Server(QObject *parent) : QObject(parent) {
|
7
|
+
Server::Server(QObject *parent, bool ignoreSslErrors) : QObject(parent) {
|
8
8
|
m_tcp_server = new QTcpServer(this);
|
9
9
|
m_page = new WebPage(this);
|
10
|
+
m_page->setIgnoreSslErrors(ignoreSslErrors);
|
10
11
|
}
|
11
12
|
|
12
13
|
bool Server::start() {
|