capybara-webkit 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ #include "SetProxy.h"
2
+ #include "WebPage.h"
3
+ #include <QNetworkAccessManager>
4
+ #include <QNetworkProxy>
5
+
6
+ SetProxy::SetProxy(WebPage *page, QObject *parent)
7
+ : Command(page, parent)
8
+ { }
9
+
10
+ void SetProxy::start(QStringList &arguments)
11
+ {
12
+ // default to empty proxy
13
+ QNetworkProxy proxy;
14
+
15
+ if (arguments.size() > 0)
16
+ proxy = QNetworkProxy(QNetworkProxy::HttpProxy,
17
+ arguments[0],
18
+ (quint16)(arguments[1].toInt()),
19
+ arguments[2],
20
+ arguments[3]);
21
+
22
+ page()->networkAccessManager()->setProxy(proxy);
23
+ emit finished(new Response(true));
24
+ }
@@ -0,0 +1,11 @@
1
+ #include "Command.h"
2
+
3
+ class WebPage;
4
+
5
+ class SetProxy : public Command {
6
+ Q_OBJECT;
7
+
8
+ public:
9
+ SetProxy(WebPage *page, QObject *parent = 0);
10
+ virtual void start(QStringList &arguments);
11
+ };
@@ -27,5 +27,6 @@ void UnsupportedContentHandler::loadUnsupportedContent() {
27
27
 
28
28
  void UnsupportedContentHandler::finish(bool success) {
29
29
  connect(m_page, SIGNAL(loadFinished(bool)), m_page, SLOT(loadFinished(bool)));
30
+ m_page->replyFinished(m_reply);
30
31
  m_page->loadFinished(success);
31
32
  }
@@ -7,7 +7,7 @@ Visit::Visit(WebPage *page, QObject *parent) : Command(page, parent) {
7
7
  }
8
8
 
9
9
  void Visit::start(QStringList &arguments) {
10
- QUrl requestedUrl = QUrl(arguments[0]);
10
+ QUrl requestedUrl = QUrl::fromEncoded(arguments[0].toUtf8(), QUrl::StrictMode);
11
11
  page()->currentFrame()->load(QUrl(requestedUrl));
12
12
  }
13
13
 
@@ -20,6 +20,7 @@ WebPage::WebPage(QObject *parent) : QWebPage(parent) {
20
20
  this, SLOT(frameCreated(QWebFrame *)));
21
21
  connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
22
22
  this, SLOT(handleUnsupportedContent(QNetworkReply*)));
23
+ this->setViewportSize(QSize(1680, 1050));
23
24
  }
24
25
 
25
26
  void WebPage::setCustomNetworkAccessManager() {
@@ -27,6 +28,7 @@ void WebPage::setCustomNetworkAccessManager() {
27
28
  manager->setCookieJar(new NetworkCookieJar());
28
29
  this->setNetworkAccessManager(manager);
29
30
  connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
31
+ connect(manager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)), this, SLOT(ignoreSslErrors(QNetworkReply *, QList<QSslError>)));
30
32
  }
31
33
 
32
34
  void WebPage::loadJavascript() {
@@ -56,6 +58,10 @@ QString WebPage::userAgentForUrl(const QUrl &url ) const {
56
58
  }
57
59
  }
58
60
 
61
+ QString WebPage::consoleMessages() {
62
+ return m_consoleMessages.join("\n");
63
+ }
64
+
59
65
  void WebPage::setUserAgent(QString userAgent) {
60
66
  m_userAgent = userAgent;
61
67
  }
@@ -88,9 +94,11 @@ QVariant WebPage::invokeCapybaraFunction(QString &name, QStringList &arguments)
88
94
  }
89
95
 
90
96
  void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
97
+ QString fullMessage = QString::number(lineNumber) + "|" + message;
91
98
  if (!sourceID.isEmpty())
92
- std::cout << qPrintable(sourceID) << ":" << lineNumber << " ";
93
- std::cout << qPrintable(message) << std::endl;
99
+ fullMessage = sourceID + "|" + fullMessage;
100
+ m_consoleMessages.append(fullMessage);
101
+ std::cout << qPrintable(fullMessage) << std::endl;
94
102
  }
95
103
 
96
104
  void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
@@ -192,6 +200,20 @@ void WebPage::replyFinished(QNetworkReply *reply) {
192
200
  }
193
201
  }
194
202
 
203
+ void WebPage::ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &errors) {
204
+ if (m_ignoreSslErrors)
205
+ reply->ignoreSslErrors(errors);
206
+ }
207
+
208
+ void WebPage::setIgnoreSslErrors(bool ignore) {
209
+ m_ignoreSslErrors = ignore;
210
+ }
211
+
212
+ bool WebPage::ignoreSslErrors() {
213
+ return m_ignoreSslErrors;
214
+ }
215
+
216
+
195
217
  int WebPage::getLastStatus() {
196
218
  return m_lastStatus;
197
219
  }
@@ -201,6 +223,10 @@ void WebPage::resetResponseHeaders() {
201
223
  m_pageHeaders = QString();
202
224
  }
203
225
 
226
+ void WebPage::resetConsoleMessages() {
227
+ m_consoleMessages.clear();
228
+ }
229
+
204
230
  QString WebPage::pageHeaders() {
205
231
  return m_pageHeaders;
206
232
  }
@@ -15,6 +15,10 @@ class WebPage : public QWebPage {
15
15
  void setCustomNetworkAccessManager();
16
16
  bool render(const QString &fileName);
17
17
  virtual bool extension (Extension extension, const ExtensionOption *option=0, ExtensionReturn *output=0);
18
+ void setIgnoreSslErrors(bool ignore);
19
+ bool ignoreSslErrors();
20
+ QString consoleMessages();
21
+ void resetConsoleMessages();
18
22
 
19
23
  public slots:
20
24
  bool shouldInterruptJavaScript();
@@ -25,6 +29,7 @@ class WebPage : public QWebPage {
25
29
  QString pageHeaders();
26
30
  void frameCreated(QWebFrame *);
27
31
  void replyFinished(QNetworkReply *reply);
32
+ void ignoreSslErrors(QNetworkReply *reply, const QList<QSslError> &);
28
33
  void handleUnsupportedContent(QNetworkReply *reply);
29
34
 
30
35
  signals:
@@ -46,5 +51,7 @@ class WebPage : public QWebPage {
46
51
  void setUserStylesheet();
47
52
  int m_lastStatus;
48
53
  QString m_pageHeaders;
54
+ bool m_ignoreSslErrors;
55
+ QStringList m_consoleMessages;
49
56
  };
50
57
 
@@ -56,10 +56,46 @@ Capybara = {
56
56
  }
57
57
  },
58
58
 
59
+ path: function(index) {
60
+ return "/" + this.getXPathNode(this.nodes[index]).join("/");
61
+ },
62
+
63
+ getXPathNode: function(node, path) {
64
+ path = path || [];
65
+ if (node.parentNode) {
66
+ path = this.getXPathNode(node.parentNode, path);
67
+ }
68
+
69
+ var first = node;
70
+ while (first.previousSibling)
71
+ first = first.previousSibling;
72
+
73
+ var count = 0;
74
+ var index = 0;
75
+ var iter = first;
76
+ while (iter) {
77
+ if (iter.nodeType == 1 && iter.nodeName == node.nodeName)
78
+ count++;
79
+ if (iter.isSameNode(node))
80
+ index = count;
81
+ iter = iter.nextSibling;
82
+ continue;
83
+ }
84
+
85
+ if (node.nodeType == 1)
86
+ path.push(node.nodeName.toLowerCase() + (node.id ? "[@id='"+node.id+"']" : count > 1 ? "["+index+"]" : ''));
87
+
88
+ return path;
89
+ },
90
+
59
91
  tagName: function(index) {
60
92
  return this.nodes[index].tagName.toLowerCase();
61
93
  },
62
94
 
95
+ submit: function(index) {
96
+ return this.nodes[index].submit();
97
+ },
98
+
63
99
  click: function (index) {
64
100
  var clickEvent = document.createEvent('MouseEvents');
65
101
  clickEvent.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
@@ -103,21 +139,25 @@ Capybara = {
103
139
  return this.nodes[index].value;
104
140
  },
105
141
 
106
- set: function(index, value) {
107
- var node = this.nodes[index];
108
- var type = (node.type || node.tagName).toLowerCase();
109
- if (type == "text" || type == "textarea" || type == "password") {
142
+ set: function (index, value) {
143
+ var length, maxLength, node, strindex, textTypes, type;
144
+
145
+ node = this.nodes[index];
146
+ type = (node.type || node.tagName).toLowerCase();
147
+ textTypes = ["email", "number", "password", "search", "tel", "text", "textarea", "url"];
148
+
149
+ if (textTypes.indexOf(type) != -1) {
110
150
  this.trigger(index, "focus");
111
- node.value = "";
112
- var maxLength = this.attribute(index, "maxlength"),
113
- length;
151
+
152
+ maxLength = this.attribute(index, "maxlength");
114
153
  if (maxLength && value.length > maxLength) {
115
154
  length = maxLength;
116
155
  } else {
117
156
  length = value.length;
118
157
  }
119
158
 
120
- for(var strindex = 0; strindex < length; strindex++) {
159
+ node.value = "";
160
+ for (strindex = 0; strindex < length; strindex++) {
121
161
  node.value += value[strindex];
122
162
  this.trigger(index, "keydown");
123
163
  this.keypress(index, false, false, false, false, 0, value[strindex]);
@@ -125,13 +165,16 @@ Capybara = {
125
165
  }
126
166
  this.trigger(index, "change");
127
167
  this.trigger(index, "blur");
128
- } else if(type == "checkbox" || type == "radio") {
129
- node.checked = (value == "true");
168
+
169
+ } else if (type === "checkbox" || type === "radio") {
170
+ node.checked = (value === "true");
130
171
  this.trigger(index, "click");
131
172
  this.trigger(index, "change");
132
- } else if(type == "file") {
173
+
174
+ } else if (type === "file") {
133
175
  this.lastAttachedFile = value;
134
176
  this.trigger(index, "click");
177
+
135
178
  } else {
136
179
  node.value = value;
137
180
  }
@@ -20,3 +20,7 @@ CHECK_COMMAND(Headers)
20
20
  CHECK_COMMAND(SetCookie)
21
21
  CHECK_COMMAND(ClearCookies)
22
22
  CHECK_COMMAND(GetCookies)
23
+ CHECK_COMMAND(Headers)
24
+ CHECK_COMMAND(SetProxy)
25
+ CHECK_COMMAND(ConsoleMessages)
26
+ CHECK_COMMAND(RequestedUrl)
@@ -18,7 +18,10 @@ int main(int argc, char **argv) {
18
18
  app.setOrganizationName("thoughtbot, inc");
19
19
  app.setOrganizationDomain("thoughtbot.com");
20
20
 
21
- Server server;
21
+ QStringList args = app.arguments();
22
+ bool ignoreSslErrors = args.contains("--ignore-ssl-errors");
23
+
24
+ Server server(0, ignoreSslErrors);
22
25
 
23
26
  if (server.start()) {
24
27
  std::cout << "Capybara-webkit server started, listening on port: " << server.server_port() << std::endl;
@@ -2,6 +2,8 @@ TEMPLATE = app
2
2
  TARGET = webkit_server
3
3
  DESTDIR = .
4
4
  HEADERS = \
5
+ RequestedUrl.h \
6
+ ConsoleMessages.h \
5
7
  WebPage.h \
6
8
  Server.h \
7
9
  Connection.h \
@@ -28,8 +30,13 @@ HEADERS = \
28
30
  SetCookie.h \
29
31
  ClearCookies.h \
30
32
  GetCookies.h \
33
+ CommandParser.h \
34
+ CommandFactory.h \
35
+ SetProxy.h \
31
36
 
32
37
  SOURCES = \
38
+ RequestedUrl.cpp \
39
+ ConsoleMessages.cpp \
33
40
  main.cpp \
34
41
  WebPage.cpp \
35
42
  Server.cpp \
@@ -57,6 +64,9 @@ SOURCES = \
57
64
  SetCookie.cpp \
58
65
  ClearCookies.cpp \
59
66
  GetCookies.cpp \
67
+ CommandParser.cpp \
68
+ CommandFactory.cpp \
69
+ SetProxy.cpp \
60
70
 
61
71
  RESOURCES = webkit_server.qrc
62
72
  QT += network webkit
metadata CHANGED
@@ -1,41 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-webkit
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 63
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 2
10
- version: 0.7.2
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - thoughtbot
14
14
  - Joe Ferris
15
+ - Matt Mongeau
16
+ - Mike Burns
15
17
  - Jason Morrison
16
- - Tristan Dunn
17
- - Joshua Clayton
18
- - Yuichi Tateno
19
- - Aaron Gibralter
20
- - Vasily Reys
21
- - petrushka
22
- - John Bintz
23
- - Chad Pytel
24
- - Christopher Meiklejohn
25
- - John Barker
26
- - Jeremy Wells
27
- - Chris Griego
28
- - Shigeya Suzuki
29
18
  autorequire:
30
19
  bindir: bin
31
20
  cert_chain: []
32
21
 
33
- date: 2011-10-07 00:00:00 -04:00
34
- default_executable:
22
+ date: 2012-01-20 00:00:00 Z
35
23
  dependencies:
36
24
  - !ruby/object:Gem::Dependency
37
- type: :runtime
38
- requirement: &id001 !ruby/object:Gem::Requirement
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
39
26
  none: false
40
27
  requirements:
41
28
  - - ">="
@@ -53,12 +40,26 @@ dependencies:
53
40
  - 1
54
41
  - 2
55
42
  version: "1.2"
56
- version_requirements: *id001
43
+ requirement: *id001
44
+ type: :runtime
45
+ prerelease: false
57
46
  name: capybara
47
+ - !ruby/object:Gem::Dependency
48
+ version_requirements: &id002 !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ hash: 3
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ requirement: *id002
58
+ type: :runtime
58
59
  prerelease: false
60
+ name: json
59
61
  - !ruby/object:Gem::Dependency
60
- type: :development
61
- requirement: &id002 !ruby/object:Gem::Requirement
62
+ version_requirements: &id003 !ruby/object:Gem::Requirement
62
63
  none: false
63
64
  requirements:
64
65
  - - ~>
@@ -69,12 +70,12 @@ dependencies:
69
70
  - 6
70
71
  - 0
71
72
  version: 2.6.0
72
- version_requirements: *id002
73
- name: rspec
73
+ requirement: *id003
74
+ type: :development
74
75
  prerelease: false
76
+ name: rspec
75
77
  - !ruby/object:Gem::Dependency
76
- type: :development
77
- requirement: &id003 !ruby/object:Gem::Requirement
78
+ version_requirements: &id004 !ruby/object:Gem::Requirement
78
79
  none: false
79
80
  requirements:
80
81
  - - ">="
@@ -83,12 +84,12 @@ dependencies:
83
84
  segments:
84
85
  - 0
85
86
  version: "0"
86
- version_requirements: *id003
87
- name: sinatra
87
+ requirement: *id004
88
+ type: :development
88
89
  prerelease: false
90
+ name: sinatra
89
91
  - !ruby/object:Gem::Dependency
90
- type: :development
91
- requirement: &id004 !ruby/object:Gem::Requirement
92
+ version_requirements: &id005 !ruby/object:Gem::Requirement
92
93
  none: false
93
94
  requirements:
94
95
  - - ">="
@@ -97,12 +98,12 @@ dependencies:
97
98
  segments:
98
99
  - 0
99
100
  version: "0"
100
- version_requirements: *id004
101
- name: mini_magick
101
+ requirement: *id005
102
+ type: :development
102
103
  prerelease: false
104
+ name: mini_magick
103
105
  - !ruby/object:Gem::Dependency
104
- type: :development
105
- requirement: &id005 !ruby/object:Gem::Requirement
106
+ version_requirements: &id006 !ruby/object:Gem::Requirement
106
107
  none: false
107
108
  requirements:
108
109
  - - ">="
@@ -111,23 +112,26 @@ dependencies:
111
112
  segments:
112
113
  - 0
113
114
  version: "0"
114
- version_requirements: *id005
115
- name: rake
115
+ requirement: *id006
116
+ type: :development
116
117
  prerelease: false
118
+ name: rake
117
119
  - !ruby/object:Gem::Dependency
118
- type: :development
119
- requirement: &id006 !ruby/object:Gem::Requirement
120
+ version_requirements: &id007 !ruby/object:Gem::Requirement
120
121
  none: false
121
122
  requirements:
122
- - - ">="
123
+ - - ~>
123
124
  - !ruby/object:Gem::Version
124
- hash: 3
125
+ hash: 15
125
126
  segments:
126
127
  - 0
127
- version: "0"
128
- version_requirements: *id006
129
- name: appraisal
128
+ - 4
129
+ - 0
130
+ version: 0.4.0
131
+ requirement: *id007
132
+ type: :development
130
133
  prerelease: false
134
+ name: appraisal
131
135
  description:
132
136
  email: support@thoughtbot.com
133
137
  executables: []
@@ -156,23 +160,34 @@ files:
156
160
  - lib/capybara-webkit.rb
157
161
  - lib/capybara/driver/webkit.rb
158
162
  - lib/capybara/driver/webkit/browser.rb
163
+ - lib/capybara/driver/webkit/cookie_jar.rb
159
164
  - lib/capybara/driver/webkit/node.rb
160
165
  - lib/capybara/driver/webkit/socket_debugger.rb
166
+ - lib/capybara/driver/webkit/version.rb
161
167
  - lib/capybara/webkit.rb
168
+ - lib/capybara/webkit/matchers.rb
162
169
  - lib/capybara_webkit_builder.rb
163
170
  - spec/browser_spec.rb
171
+ - spec/cookie_jar_spec.rb
164
172
  - spec/driver_rendering_spec.rb
165
173
  - spec/driver_spec.rb
166
174
  - spec/integration/driver_spec.rb
167
175
  - spec/integration/session_spec.rb
176
+ - spec/self_signed_ssl_cert.rb
168
177
  - spec/spec_helper.rb
169
178
  - src/Body.h
170
179
  - src/ClearCookies.cpp
171
180
  - src/ClearCookies.h
172
181
  - src/Command.cpp
173
182
  - src/Command.h
183
+ - src/CommandFactory.cpp
184
+ - src/CommandFactory.h
185
+ - src/CommandParser.cpp
186
+ - src/CommandParser.h
174
187
  - src/Connection.cpp
175
188
  - src/Connection.h
189
+ - src/ConsoleMessages.cpp
190
+ - src/ConsoleMessages.h
176
191
  - src/Evaluate.cpp
177
192
  - src/Evaluate.h
178
193
  - src/Execute.cpp
@@ -197,6 +212,8 @@ files:
197
212
  - src/Node.h
198
213
  - src/Render.cpp
199
214
  - src/Render.h
215
+ - src/RequestedUrl.cpp
216
+ - src/RequestedUrl.h
200
217
  - src/Reset.cpp
201
218
  - src/Reset.h
202
219
  - src/Response.cpp
@@ -205,6 +222,8 @@ files:
205
222
  - src/Server.h
206
223
  - src/SetCookie.cpp
207
224
  - src/SetCookie.h
225
+ - src/SetProxy.cpp
226
+ - src/SetProxy.h
208
227
  - src/Source.cpp
209
228
  - src/Source.h
210
229
  - src/Status.cpp
@@ -226,7 +245,6 @@ files:
226
245
  - templates/Command.cpp
227
246
  - templates/Command.h
228
247
  - webkit_server.pro
229
- has_rdoc: true
230
248
  homepage: http://github.com/thoughtbot/capybara-webkit
231
249
  licenses: []
232
250
 
@@ -256,14 +274,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
274
  requirements: []
257
275
 
258
276
  rubyforge_project:
259
- rubygems_version: 1.6.1
277
+ rubygems_version: 1.8.11
260
278
  signing_key:
261
279
  specification_version: 3
262
280
  summary: Headless Webkit driver for Capybara
263
281
  test_files:
264
282
  - spec/browser_spec.rb
283
+ - spec/cookie_jar_spec.rb
265
284
  - spec/driver_rendering_spec.rb
266
285
  - spec/driver_spec.rb
267
286
  - spec/integration/driver_spec.rb
268
287
  - spec/integration/session_spec.rb
288
+ - spec/self_signed_ssl_cert.rb
269
289
  - spec/spec_helper.rb