otherinbox-capybara-webkit 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/.gitignore +19 -0
  2. data/.rspec +2 -0
  3. data/Appraisals +7 -0
  4. data/CONTRIBUTING.md +47 -0
  5. data/ChangeLog +70 -0
  6. data/Gemfile +3 -0
  7. data/Gemfile.lock +68 -0
  8. data/LICENSE +19 -0
  9. data/NEWS.md +36 -0
  10. data/README.md +114 -0
  11. data/Rakefile +65 -0
  12. data/bin/Info.plist +22 -0
  13. data/capybara-webkit.gemspec +28 -0
  14. data/extconf.rb +2 -0
  15. data/gemfiles/1.0.gemfile +7 -0
  16. data/gemfiles/1.0.gemfile.lock +70 -0
  17. data/gemfiles/1.1.gemfile +7 -0
  18. data/gemfiles/1.1.gemfile.lock +70 -0
  19. data/lib/capybara-webkit.rb +1 -0
  20. data/lib/capybara/driver/webkit.rb +135 -0
  21. data/lib/capybara/driver/webkit/browser.rb +168 -0
  22. data/lib/capybara/driver/webkit/connection.rb +120 -0
  23. data/lib/capybara/driver/webkit/cookie_jar.rb +55 -0
  24. data/lib/capybara/driver/webkit/node.rb +118 -0
  25. data/lib/capybara/driver/webkit/socket_debugger.rb +43 -0
  26. data/lib/capybara/driver/webkit/version.rb +7 -0
  27. data/lib/capybara/webkit.rb +11 -0
  28. data/lib/capybara/webkit/matchers.rb +37 -0
  29. data/lib/capybara_webkit_builder.rb +68 -0
  30. data/spec/browser_spec.rb +248 -0
  31. data/spec/capybara_webkit_builder_spec.rb +37 -0
  32. data/spec/connection_spec.rb +54 -0
  33. data/spec/cookie_jar_spec.rb +48 -0
  34. data/spec/driver_rendering_spec.rb +80 -0
  35. data/spec/driver_resize_window_spec.rb +59 -0
  36. data/spec/driver_spec.rb +1552 -0
  37. data/spec/integration/driver_spec.rb +20 -0
  38. data/spec/integration/session_spec.rb +137 -0
  39. data/spec/self_signed_ssl_cert.rb +42 -0
  40. data/spec/spec_helper.rb +46 -0
  41. data/src/Body.h +12 -0
  42. data/src/ClearCookies.cpp +15 -0
  43. data/src/ClearCookies.h +11 -0
  44. data/src/Command.cpp +19 -0
  45. data/src/Command.h +31 -0
  46. data/src/CommandFactory.cpp +38 -0
  47. data/src/CommandFactory.h +16 -0
  48. data/src/CommandParser.cpp +76 -0
  49. data/src/CommandParser.h +33 -0
  50. data/src/Connection.cpp +71 -0
  51. data/src/Connection.h +37 -0
  52. data/src/ConsoleMessages.cpp +10 -0
  53. data/src/ConsoleMessages.h +12 -0
  54. data/src/CurrentUrl.cpp +68 -0
  55. data/src/CurrentUrl.h +16 -0
  56. data/src/Evaluate.cpp +84 -0
  57. data/src/Evaluate.h +22 -0
  58. data/src/Execute.cpp +16 -0
  59. data/src/Execute.h +12 -0
  60. data/src/Find.cpp +19 -0
  61. data/src/Find.h +13 -0
  62. data/src/FrameFocus.cpp +66 -0
  63. data/src/FrameFocus.h +28 -0
  64. data/src/GetCookies.cpp +20 -0
  65. data/src/GetCookies.h +14 -0
  66. data/src/Header.cpp +18 -0
  67. data/src/Header.h +11 -0
  68. data/src/Headers.cpp +10 -0
  69. data/src/Headers.h +12 -0
  70. data/src/IgnoreSslErrors.cpp +12 -0
  71. data/src/IgnoreSslErrors.h +12 -0
  72. data/src/JavascriptInvocation.cpp +14 -0
  73. data/src/JavascriptInvocation.h +19 -0
  74. data/src/NetworkAccessManager.cpp +29 -0
  75. data/src/NetworkAccessManager.h +19 -0
  76. data/src/NetworkCookieJar.cpp +101 -0
  77. data/src/NetworkCookieJar.h +15 -0
  78. data/src/Node.cpp +14 -0
  79. data/src/Node.h +13 -0
  80. data/src/NullCommand.cpp +10 -0
  81. data/src/NullCommand.h +11 -0
  82. data/src/PageLoadingCommand.cpp +46 -0
  83. data/src/PageLoadingCommand.h +40 -0
  84. data/src/Render.cpp +18 -0
  85. data/src/Render.h +12 -0
  86. data/src/RequestedUrl.cpp +12 -0
  87. data/src/RequestedUrl.h +12 -0
  88. data/src/Reset.cpp +29 -0
  89. data/src/Reset.h +15 -0
  90. data/src/ResizeWindow.cpp +16 -0
  91. data/src/ResizeWindow.h +12 -0
  92. data/src/Response.cpp +24 -0
  93. data/src/Response.h +15 -0
  94. data/src/Server.cpp +24 -0
  95. data/src/Server.h +21 -0
  96. data/src/SetCookie.cpp +16 -0
  97. data/src/SetCookie.h +11 -0
  98. data/src/SetProxy.cpp +22 -0
  99. data/src/SetProxy.h +11 -0
  100. data/src/SetSkipImageLoading.cpp +11 -0
  101. data/src/SetSkipImageLoading.h +11 -0
  102. data/src/Source.cpp +18 -0
  103. data/src/Source.h +19 -0
  104. data/src/Status.cpp +12 -0
  105. data/src/Status.h +12 -0
  106. data/src/UnsupportedContentHandler.cpp +32 -0
  107. data/src/UnsupportedContentHandler.h +18 -0
  108. data/src/Url.cpp +12 -0
  109. data/src/Url.h +12 -0
  110. data/src/Visit.cpp +12 -0
  111. data/src/Visit.h +12 -0
  112. data/src/WebPage.cpp +246 -0
  113. data/src/WebPage.h +58 -0
  114. data/src/body.cpp +10 -0
  115. data/src/capybara.js +315 -0
  116. data/src/find_command.h +30 -0
  117. data/src/main.cpp +31 -0
  118. data/src/webkit_server.pro +87 -0
  119. data/src/webkit_server.qrc +5 -0
  120. data/templates/Command.cpp +10 -0
  121. data/templates/Command.h +12 -0
  122. data/webkit_server.pro +4 -0
  123. metadata +300 -0
data/src/FrameFocus.h ADDED
@@ -0,0 +1,28 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+ class QWebFrame;
5
+
6
+ class FrameFocus : public Command {
7
+ Q_OBJECT
8
+
9
+ public:
10
+ FrameFocus(WebPage *page, QStringList &arguments, QObject *parent = 0);
11
+ virtual void start();
12
+
13
+ private:
14
+ void findFrames();
15
+
16
+ void focusParent();
17
+
18
+ void focusIndex(int index);
19
+ bool isFrameAtIndex(int index);
20
+
21
+ void focusId(QString id);
22
+
23
+ void success();
24
+ void frameNotFound();
25
+
26
+ QList<QWebFrame *> frames;
27
+ };
28
+
@@ -0,0 +1,20 @@
1
+ #include "GetCookies.h"
2
+ #include "WebPage.h"
3
+ #include "NetworkCookieJar.h"
4
+
5
+ GetCookies::GetCookies(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent)
6
+ {
7
+ m_buffer = "";
8
+ }
9
+
10
+ void GetCookies::start()
11
+ {
12
+ NetworkCookieJar *jar = qobject_cast<NetworkCookieJar*>(page()
13
+ ->networkAccessManager()
14
+ ->cookieJar());
15
+ foreach (QNetworkCookie cookie, jar->getAllCookies()) {
16
+ m_buffer.append(cookie.toRawForm());
17
+ m_buffer.append("\n");
18
+ }
19
+ emit finished(new Response(true, m_buffer));
20
+ }
data/src/GetCookies.h ADDED
@@ -0,0 +1,14 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class GetCookies : public Command {
6
+ Q_OBJECT;
7
+
8
+ public:
9
+ GetCookies(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+
12
+ private:
13
+ QString m_buffer;
14
+ };
data/src/Header.cpp ADDED
@@ -0,0 +1,18 @@
1
+ #include "Header.h"
2
+ #include "WebPage.h"
3
+ #include "NetworkAccessManager.h"
4
+
5
+ Header::Header(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
6
+ }
7
+
8
+ void Header::start() {
9
+ QString key = arguments()[0];
10
+ QString value = arguments()[1];
11
+ NetworkAccessManager* networkAccessManager = qobject_cast<NetworkAccessManager*>(page()->networkAccessManager());
12
+ if (key.toLower().replace("-", "_") == "user_agent") {
13
+ page()->setUserAgent(value);
14
+ } else {
15
+ networkAccessManager->addHeader(key, value);
16
+ }
17
+ emit finished(new Response(true));
18
+ }
data/src/Header.h ADDED
@@ -0,0 +1,11 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Header : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Header(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
data/src/Headers.cpp ADDED
@@ -0,0 +1,10 @@
1
+ #include "Headers.h"
2
+ #include "WebPage.h"
3
+
4
+ Headers::Headers(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ }
6
+
7
+ void Headers::start() {
8
+ emit finished(new Response(true, page()->pageHeaders()));
9
+ }
10
+
data/src/Headers.h ADDED
@@ -0,0 +1,12 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class Headers : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ Headers(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
@@ -0,0 +1,12 @@
1
+ #include "IgnoreSslErrors.h"
2
+ #include "WebPage.h"
3
+
4
+ IgnoreSslErrors::IgnoreSslErrors(WebPage *page, QStringList &arguments, QObject *parent) :
5
+ Command(page, arguments, parent) {
6
+ }
7
+
8
+ void IgnoreSslErrors::start() {
9
+ page()->ignoreSslErrors();
10
+ emit finished(new Response(true));
11
+ }
12
+
@@ -0,0 +1,12 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class IgnoreSslErrors : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ IgnoreSslErrors(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
12
+
@@ -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,29 @@
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
+
26
+ void NetworkAccessManager::resetHeaders() {
27
+ m_headers.clear();
28
+ };
29
+
@@ -0,0 +1,19 @@
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
+ void resetHeaders();
13
+
14
+ protected:
15
+ QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData);
16
+
17
+ private:
18
+ QHash<QString, QString> m_headers;
19
+ };
@@ -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 &current = 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 &current = 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, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
5
+ }
6
+
7
+ void Node::start() {
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
@@ -0,0 +1,13 @@
1
+ #include "Command.h"
2
+ #include <QStringList>
3
+
4
+ class WebPage;
5
+
6
+ class Node : public Command {
7
+ Q_OBJECT
8
+
9
+ public:
10
+ Node(WebPage *page, QStringList &arguments, QObject *parent = 0);
11
+ virtual void start();
12
+ };
13
+
@@ -0,0 +1,10 @@
1
+ #include "NullCommand.h"
2
+ #include "WebPage.h"
3
+
4
+ NullCommand::NullCommand(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {}
5
+
6
+ void NullCommand::start() {
7
+ QString failure = QString("[Capybara WebKit] Unknown command: ") + arguments()[0] + "\n";
8
+ emit finished(new Response(false, failure));
9
+ }
10
+
data/src/NullCommand.h ADDED
@@ -0,0 +1,11 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class NullCommand : public Command {
6
+ Q_OBJECT
7
+
8
+ public:
9
+ NullCommand(WebPage *page, QStringList &arguments, QObject *parent = 0);
10
+ virtual void start();
11
+ };
@@ -0,0 +1,46 @@
1
+ #include "PageLoadingCommand.h"
2
+ #include "Command.h"
3
+ #include "WebPage.h"
4
+
5
+ PageLoadingCommand::PageLoadingCommand(Command *command, WebPage *page, QObject *parent) : QObject(parent) {
6
+ m_page = page;
7
+ m_command = command;
8
+ m_pageLoadingFromCommand = false;
9
+ m_pageSuccess = true;
10
+ m_pendingResponse = NULL;
11
+ connect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
12
+ connect(m_page, SIGNAL(pageFinished(bool)), this, SLOT(pendingLoadFinished(bool)));
13
+ }
14
+
15
+ void PageLoadingCommand::start() {
16
+ connect(m_command, SIGNAL(finished(Response *)), this, SLOT(commandFinished(Response *)));
17
+ m_command->start();
18
+ };
19
+
20
+ void PageLoadingCommand::pendingLoadFinished(bool success) {
21
+ m_pageSuccess = success;
22
+ if (m_pageLoadingFromCommand) {
23
+ m_pageLoadingFromCommand = false;
24
+ if (m_pendingResponse) {
25
+ if (m_pageSuccess) {
26
+ emit finished(m_pendingResponse);
27
+ } else {
28
+ QString message = m_page->failureString();
29
+ emit finished(new Response(false, message));
30
+ }
31
+ }
32
+ }
33
+ }
34
+
35
+ void PageLoadingCommand::pageLoadingFromCommand() {
36
+ m_pageLoadingFromCommand = true;
37
+ }
38
+
39
+ void PageLoadingCommand::commandFinished(Response *response) {
40
+ disconnect(m_page, SIGNAL(loadStarted()), this, SLOT(pageLoadingFromCommand()));
41
+ m_command->deleteLater();
42
+ if (m_pageLoadingFromCommand)
43
+ m_pendingResponse = response;
44
+ else
45
+ emit finished(response);
46
+ }