capybara-webkit 1.14.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +8 -9
- data/Appraisals +3 -9
- data/Gemfile +0 -1
- data/Gemfile.lock +41 -41
- data/NEWS.md +14 -0
- data/README.md +2 -2
- data/capybara-webkit.gemspec +2 -2
- data/gemfiles/2.15.gemfile +10 -0
- data/gemfiles/master.gemfile +3 -4
- data/lib/capybara/webkit/browser.rb +14 -5
- data/lib/capybara/webkit/driver.rb +14 -1
- data/lib/capybara/webkit/node.rb +39 -24
- data/lib/capybara/webkit/server.rb +38 -5
- data/lib/capybara/webkit/version.rb +1 -1
- data/lib/capybara_webkit_builder.rb +3 -1
- data/spec/driver_spec.rb +110 -21
- data/spec/fixtures/exit_text.rb +9 -0
- data/spec/integration/session_spec.rb +69 -0
- data/spec/node_spec.rb +90 -0
- data/spec/server_spec.rb +9 -2
- data/spec/spec_helper.rb +4 -1
- data/spec/support/matchers/include_response.rb +5 -1
- data/src/CommandFactory.cpp +2 -0
- data/src/Connection.cpp +2 -2
- data/src/Evaluate.cpp +2 -2
- data/src/EvaluateAsync.cpp +54 -0
- data/src/EvaluateAsync.h +14 -0
- data/src/JavascriptInvocation.cpp +37 -13
- data/src/JavascriptInvocation.h +6 -3
- data/src/Node.cpp +9 -1
- data/src/PageLoadingCommand.cpp +4 -4
- data/src/Refresh.cpp +12 -0
- data/src/Refresh.h +10 -0
- data/src/TimeoutCommand.cpp +1 -1
- data/src/WebPage.cpp +8 -7
- data/src/WebPage.h +1 -1
- data/src/WebPageManager.cpp +8 -8
- data/src/WebPageManager.h +1 -1
- data/src/capybara.js +71 -44
- data/src/find_command.h +2 -0
- data/src/webkit_server.pro +4 -0
- metadata +39 -14
- data/gemfiles/2.13.gemfile +0 -11
- data/gemfiles/2.7.gemfile +0 -12
data/src/WebPage.h
CHANGED
@@ -50,7 +50,7 @@ class WebPage : public QWebPage {
|
|
50
50
|
QVariantMap pageHeaders();
|
51
51
|
QByteArray body();
|
52
52
|
QString contentType();
|
53
|
-
void mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button);
|
53
|
+
void mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
|
54
54
|
bool clickTest(QWebElement element, int absoluteX, int absoluteY);
|
55
55
|
void resize(int, int);
|
56
56
|
int modalCount();
|
data/src/WebPageManager.cpp
CHANGED
@@ -81,14 +81,14 @@ void WebPageManager::removePage(WebPage *page) {
|
|
81
81
|
|
82
82
|
void WebPageManager::emitLoadStarted() {
|
83
83
|
if (m_started.empty()) {
|
84
|
-
|
84
|
+
log() << "Load started";
|
85
85
|
emit loadStarted();
|
86
86
|
}
|
87
87
|
m_started += qobject_cast<WebPage *>(sender());
|
88
88
|
}
|
89
89
|
|
90
90
|
void WebPageManager::requestCreated(QByteArray &url, QNetworkReply *reply) {
|
91
|
-
|
91
|
+
log() << "Started request to" << url;
|
92
92
|
if (reply->isFinished())
|
93
93
|
replyFinished(reply);
|
94
94
|
else {
|
@@ -110,7 +110,7 @@ void WebPageManager::handleReplyFinished() {
|
|
110
110
|
|
111
111
|
void WebPageManager::replyFinished(QNetworkReply *reply) {
|
112
112
|
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
113
|
-
|
113
|
+
log() << "Received" << status << "from" << reply->url().toString();
|
114
114
|
m_pendingReplies.removeAll(reply);
|
115
115
|
}
|
116
116
|
|
@@ -119,7 +119,7 @@ void WebPageManager::replyDestroyed(QObject *reply) {
|
|
119
119
|
}
|
120
120
|
|
121
121
|
void WebPageManager::setPageStatus(bool success) {
|
122
|
-
|
122
|
+
log() << "Page finished with" << success;
|
123
123
|
m_started.remove(qobject_cast<WebPage *>(sender()));
|
124
124
|
m_success = success && m_success;
|
125
125
|
if (m_started.empty()) {
|
@@ -128,7 +128,7 @@ void WebPageManager::setPageStatus(bool success) {
|
|
128
128
|
}
|
129
129
|
|
130
130
|
void WebPageManager::emitPageFinished() {
|
131
|
-
|
131
|
+
log() << "Load finished";
|
132
132
|
emit pageFinished(m_success);
|
133
133
|
m_success = true;
|
134
134
|
}
|
@@ -151,7 +151,7 @@ void WebPageManager::setTimeout(int timeout) {
|
|
151
151
|
|
152
152
|
void WebPageManager::reset() {
|
153
153
|
foreach(QNetworkReply *reply, m_pendingReplies) {
|
154
|
-
|
154
|
+
log() << "Aborting request to" << reply->url().toString();
|
155
155
|
reply->abort();
|
156
156
|
}
|
157
157
|
m_pendingReplies.clear();
|
@@ -191,9 +191,9 @@ bool WebPageManager::isLoading() const {
|
|
191
191
|
return false;
|
192
192
|
}
|
193
193
|
|
194
|
-
QDebug WebPageManager::
|
194
|
+
QDebug WebPageManager::log() const {
|
195
195
|
if (m_loggingEnabled) {
|
196
|
-
return qCritical();
|
196
|
+
return qCritical() << qPrintable(QTime::currentTime().toString("hh:mm:ss.zzz"));
|
197
197
|
} else {
|
198
198
|
return QDebug(m_ignoredOutput);
|
199
199
|
}
|
data/src/WebPageManager.h
CHANGED
@@ -33,7 +33,7 @@ class WebPageManager : public QObject {
|
|
33
33
|
void reset();
|
34
34
|
NetworkCookieJar *cookieJar();
|
35
35
|
bool isLoading() const;
|
36
|
-
QDebug
|
36
|
+
QDebug log() const;
|
37
37
|
void enableLogging();
|
38
38
|
void replyFinished(QNetworkReply *reply);
|
39
39
|
NetworkAccessManager *networkAccessManager();
|
data/src/capybara.js
CHANGED
@@ -7,7 +7,15 @@ Capybara = {
|
|
7
7
|
invoke: function () {
|
8
8
|
try {
|
9
9
|
if (CapybaraInvocation.functionName == "leftClick") {
|
10
|
-
|
10
|
+
var args = CapybaraInvocation.arguments;
|
11
|
+
var leftClickOptions = this["verifiedClickPosition"].apply(this, args);
|
12
|
+
leftClickOptions["keys"] = JSON.parse(args[1]);
|
13
|
+
offset = JSON.parse(args[2]);
|
14
|
+
if (offset && offset.x && offset.y){
|
15
|
+
leftClickOptions["absoluteX"] = leftClickOptions["absoluteLeft"] + offset.x;
|
16
|
+
leftClickOptions["absoluteY"] = leftClickOptions["absoluteTop"] + offset.y;
|
17
|
+
}
|
18
|
+
return leftClickOptions;
|
11
19
|
} else {
|
12
20
|
return this[CapybaraInvocation.functionName].apply(this, CapybaraInvocation.arguments);
|
13
21
|
}
|
@@ -66,7 +74,8 @@ Capybara = {
|
|
66
74
|
|
67
75
|
text: function (index) {
|
68
76
|
var node = this.getNode(index);
|
69
|
-
var type = (node.type || node.tagName).toLowerCase();
|
77
|
+
var type = node instanceof HTMLFormElement ? 'form' : (node.type || node.tagName).toLowerCase();
|
78
|
+
|
70
79
|
if (!this.isNodeVisible(node)) {
|
71
80
|
return '';
|
72
81
|
} else if (type == "textarea") {
|
@@ -84,22 +93,15 @@ Capybara = {
|
|
84
93
|
|
85
94
|
attribute: function (index, name) {
|
86
95
|
var node = this.getNode(index);
|
87
|
-
|
88
|
-
case 'checked':
|
89
|
-
return node.checked;
|
90
|
-
break;
|
91
|
-
|
92
|
-
case 'disabled':
|
93
|
-
return node.disabled;
|
94
|
-
break;
|
95
|
-
|
96
|
-
case 'multiple':
|
97
|
-
return node.multiple;
|
98
|
-
break;
|
99
|
-
|
100
|
-
default:
|
96
|
+
if (node.hasAttribute(name)) {
|
101
97
|
return node.getAttribute(name);
|
102
98
|
}
|
99
|
+
return void 0;
|
100
|
+
},
|
101
|
+
|
102
|
+
property: function (index, name) {
|
103
|
+
var node = this.getNode(index);
|
104
|
+
return node[name];
|
103
105
|
},
|
104
106
|
|
105
107
|
hasAttribute: function(index, name) {
|
@@ -214,22 +216,28 @@ Capybara = {
|
|
214
216
|
return pos;
|
215
217
|
},
|
216
218
|
|
217
|
-
click: function (index, action) {
|
219
|
+
click: function (index, action, keys, offset) {
|
218
220
|
var pos = this.verifiedClickPosition(index);
|
219
|
-
|
221
|
+
keys = keys ? JSON.parse(keys) : [];
|
222
|
+
offset = offset ? JSON.parse(offset) : {};
|
223
|
+
if (offset && (offset.x != null) && (offset.y != null)){
|
224
|
+
action(pos.absoluteLeft + offset.x, pos.absoluteTop + offset.y, keys);
|
225
|
+
} else {
|
226
|
+
action(pos.absoluteX, pos.absoluteY, keys);
|
227
|
+
}
|
220
228
|
},
|
221
229
|
|
222
|
-
leftClick: function (index) {
|
223
|
-
this.click(index, CapybaraInvocation.leftClick);
|
230
|
+
leftClick: function (index, keys, offset) {
|
231
|
+
this.click(index, CapybaraInvocation.leftClick, keys, offset);
|
224
232
|
},
|
225
233
|
|
226
|
-
doubleClick: function(index) {
|
227
|
-
this.click(index, CapybaraInvocation.leftClick);
|
228
|
-
this.click(index, CapybaraInvocation.doubleClick);
|
234
|
+
doubleClick: function(index, keys, offset) {
|
235
|
+
this.click(index, CapybaraInvocation.leftClick, keys, offset);
|
236
|
+
this.click(index, CapybaraInvocation.doubleClick, keys, offset);
|
229
237
|
},
|
230
238
|
|
231
|
-
rightClick: function(index) {
|
232
|
-
this.click(index, CapybaraInvocation.rightClick);
|
239
|
+
rightClick: function(index, keys, offset) {
|
240
|
+
this.click(index, CapybaraInvocation.rightClick, keys, offset);
|
233
241
|
},
|
234
242
|
|
235
243
|
hover: function (index) {
|
@@ -255,12 +263,18 @@ Capybara = {
|
|
255
263
|
},
|
256
264
|
|
257
265
|
isNodeVisible: function(node) {
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
266
|
+
var style = node.ownerDocument.defaultView.getComputedStyle(node, null);
|
267
|
+
// Only check computed visibility style on current node since it
|
268
|
+
// will inherit from nearest ancestor with a setting and overrides
|
269
|
+
// any farther ancestors
|
270
|
+
if (style.getPropertyValue('visibility') == 'hidden' || style.getPropertyValue('display') == 'none')
|
271
|
+
return false;
|
262
272
|
|
263
|
-
|
273
|
+
// Must check CSS display setting for all ancestors
|
274
|
+
while (node = node.parentElement) {
|
275
|
+
style = node.ownerDocument.defaultView.getComputedStyle(node, null);
|
276
|
+
if (style.getPropertyValue('display') == 'none' )
|
277
|
+
return false;
|
264
278
|
}
|
265
279
|
return true;
|
266
280
|
},
|
@@ -390,30 +404,39 @@ Capybara = {
|
|
390
404
|
elem.focus();
|
391
405
|
},
|
392
406
|
|
393
|
-
selectOption: function(index)
|
407
|
+
selectOption: function(index){
|
408
|
+
this._setOption(index, true);
|
409
|
+
},
|
410
|
+
|
411
|
+
unselectOption: function(index){
|
412
|
+
this._setOption(index, false);
|
413
|
+
},
|
414
|
+
|
415
|
+
_setOption: function(index, state) {
|
394
416
|
var optionNode = this.getNode(index);
|
395
417
|
var selectNode = optionNode.parentNode;
|
418
|
+
if (selectNode.tagName == "OPTGROUP")
|
419
|
+
selectNode = selectNode.parentNode;
|
396
420
|
|
397
421
|
if (optionNode.disabled)
|
398
422
|
return;
|
399
423
|
|
424
|
+
if ((!selectNode.multiple) && (!state))
|
425
|
+
return;
|
426
|
+
|
400
427
|
// click on select list
|
401
428
|
this.triggerOnNode(selectNode, 'mousedown');
|
402
429
|
selectNode.focus();
|
403
|
-
this.triggerOnNode(selectNode, '
|
404
|
-
this.triggerOnNode(selectNode, 'click');
|
430
|
+
this.triggerOnNode(selectNode, 'input');
|
405
431
|
|
406
|
-
// select option from list
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
this.triggerOnNode(optionNode, 'click');
|
412
|
-
},
|
432
|
+
// select/deselect option from list
|
433
|
+
if (optionNode.selected != state){
|
434
|
+
optionNode.selected = state;
|
435
|
+
this.triggerOnNode(selectNode, 'change');
|
436
|
+
}
|
413
437
|
|
414
|
-
|
415
|
-
this.
|
416
|
-
this.trigger(index, "change");
|
438
|
+
this.triggerOnNode(selectNode, 'mouseup');
|
439
|
+
this.triggerOnNode(selectNode, 'click');
|
417
440
|
},
|
418
441
|
|
419
442
|
centerPosition: function(element) {
|
@@ -493,12 +516,16 @@ Capybara = {
|
|
493
516
|
return {'element-581e-422e-8be1-884c4e116226': this.registerNode(arg)};
|
494
517
|
} else if (arg === null) {
|
495
518
|
return undefined;
|
519
|
+
} else if (arg instanceof Date){
|
520
|
+
return arg;
|
496
521
|
} else if ( typeof arg == 'object' ) {
|
497
522
|
this._visitedObjects.push(arg);
|
523
|
+
var result = {};
|
498
524
|
for(var _k in arg){
|
499
|
-
|
525
|
+
result[_k] = this.wrapResult(arg[_k]);
|
500
526
|
}
|
501
527
|
this._visitedObjects.pop();
|
528
|
+
return result;
|
502
529
|
}
|
503
530
|
return arg;
|
504
531
|
}
|
data/src/find_command.h
CHANGED
@@ -8,6 +8,7 @@ CHECK_COMMAND(FindXpath)
|
|
8
8
|
CHECK_COMMAND(Reset)
|
9
9
|
CHECK_COMMAND(Node)
|
10
10
|
CHECK_COMMAND(Evaluate)
|
11
|
+
CHECK_COMMAND(EvaluateAsync)
|
11
12
|
CHECK_COMMAND(Execute)
|
12
13
|
CHECK_COMMAND(FrameFocus)
|
13
14
|
CHECK_COMMAND(Header)
|
@@ -48,6 +49,7 @@ CHECK_COMMAND(WindowSize)
|
|
48
49
|
CHECK_COMMAND(WindowMaximize)
|
49
50
|
CHECK_COMMAND(GoBack)
|
50
51
|
CHECK_COMMAND(GoForward)
|
52
|
+
CHECK_COMMAND(Refresh)
|
51
53
|
CHECK_COMMAND(AcceptAlert)
|
52
54
|
CHECK_COMMAND(FindModal)
|
53
55
|
CHECK_COMMAND(SetUnknownUrlMode)
|
data/src/webkit_server.pro
CHANGED
@@ -17,6 +17,7 @@ HEADERS = \
|
|
17
17
|
AcceptAlert.h \
|
18
18
|
GoForward.h \
|
19
19
|
GoBack.h \
|
20
|
+
Refresh.h \
|
20
21
|
WindowMaximize.h \
|
21
22
|
WindowSize.h \
|
22
23
|
WindowCommand.h \
|
@@ -46,6 +47,7 @@ HEADERS = \
|
|
46
47
|
Node.h \
|
47
48
|
JavascriptInvocation.h \
|
48
49
|
Evaluate.h \
|
50
|
+
EvaluateAsync.h \
|
49
51
|
Execute.h \
|
50
52
|
FrameFocus.h \
|
51
53
|
Response.h \
|
@@ -100,6 +102,7 @@ SOURCES = \
|
|
100
102
|
AcceptAlert.cpp \
|
101
103
|
GoForward.cpp \
|
102
104
|
GoBack.cpp \
|
105
|
+
Refresh.cpp \
|
103
106
|
WindowMaximize.cpp \
|
104
107
|
WindowSize.cpp \
|
105
108
|
WindowCommand.cpp \
|
@@ -130,6 +133,7 @@ SOURCES = \
|
|
130
133
|
Node.cpp \
|
131
134
|
JavascriptInvocation.cpp \
|
132
135
|
Evaluate.cpp \
|
136
|
+
EvaluateAsync.cpp \
|
133
137
|
Execute.cpp \
|
134
138
|
FrameFocus.cpp \
|
135
139
|
Response.cpp \
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara-webkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thoughtbot
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2018-02-07 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: capybara
|
@@ -21,20 +21,20 @@ dependencies:
|
|
21
21
|
requirements:
|
22
22
|
- - ">="
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 2.3
|
24
|
+
version: '2.3'
|
25
25
|
- - "<"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: '4.0'
|
28
28
|
type: :runtime
|
29
29
|
prerelease: false
|
30
30
|
version_requirements: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - ">="
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 2.3
|
34
|
+
version: '2.3'
|
35
35
|
- - "<"
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version:
|
37
|
+
version: '4.0'
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: json
|
40
40
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,16 +109,16 @@ dependencies:
|
|
109
109
|
name: appraisal
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
111
111
|
requirements:
|
112
|
-
- - "
|
112
|
+
- - ">="
|
113
113
|
- !ruby/object:Gem::Version
|
114
|
-
version: 0
|
114
|
+
version: '0'
|
115
115
|
type: :development
|
116
116
|
prerelease: false
|
117
117
|
version_requirements: !ruby/object:Gem::Requirement
|
118
118
|
requirements:
|
119
|
-
- - "
|
119
|
+
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version: 0
|
121
|
+
version: '0'
|
122
122
|
- !ruby/object:Gem::Dependency
|
123
123
|
name: launchy
|
124
124
|
requirement: !ruby/object:Gem::Requirement
|
@@ -155,8 +155,7 @@ files:
|
|
155
155
|
- bin/Info.plist
|
156
156
|
- capybara-webkit.gemspec
|
157
157
|
- extconf.rb
|
158
|
-
- gemfiles/2.
|
159
|
-
- gemfiles/2.7.gemfile
|
158
|
+
- gemfiles/2.15.gemfile
|
160
159
|
- gemfiles/master.gemfile
|
161
160
|
- lib/capybara-webkit.rb
|
162
161
|
- lib/capybara/webkit.rb
|
@@ -180,8 +179,10 @@ files:
|
|
180
179
|
- spec/driver_resize_window_spec.rb
|
181
180
|
- spec/driver_spec.rb
|
182
181
|
- spec/errors_spec.rb
|
182
|
+
- spec/fixtures/exit_text.rb
|
183
183
|
- spec/fixtures/fake_server.sh
|
184
184
|
- spec/integration/session_spec.rb
|
185
|
+
- spec/node_spec.rb
|
185
186
|
- spec/selenium_compatibility_spec.rb
|
186
187
|
- spec/self_signed_ssl_cert.rb
|
187
188
|
- spec/server_spec.rb
|
@@ -224,6 +225,8 @@ files:
|
|
224
225
|
- src/ErrorMessage.h
|
225
226
|
- src/Evaluate.cpp
|
226
227
|
- src/Evaluate.h
|
228
|
+
- src/EvaluateAsync.cpp
|
229
|
+
- src/EvaluateAsync.h
|
227
230
|
- src/Execute.cpp
|
228
231
|
- src/Execute.h
|
229
232
|
- src/FindCss.cpp
|
@@ -286,6 +289,8 @@ files:
|
|
286
289
|
- src/NullCommand.h
|
287
290
|
- src/PageLoadingCommand.cpp
|
288
291
|
- src/PageLoadingCommand.h
|
292
|
+
- src/Refresh.cpp
|
293
|
+
- src/Refresh.h
|
289
294
|
- src/Render.cpp
|
290
295
|
- src/Render.h
|
291
296
|
- src/RequestHandler.cpp
|
@@ -385,8 +390,28 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
385
390
|
requirements:
|
386
391
|
- Qt >= 4.8
|
387
392
|
rubyforge_project:
|
388
|
-
rubygems_version: 2.4
|
393
|
+
rubygems_version: 2.7.4
|
389
394
|
signing_key:
|
390
395
|
specification_version: 4
|
391
396
|
summary: Headless Webkit driver for Capybara
|
392
|
-
test_files:
|
397
|
+
test_files:
|
398
|
+
- spec/browser_spec.rb
|
399
|
+
- spec/capybara_webkit_builder_spec.rb
|
400
|
+
- spec/configuration_spec.rb
|
401
|
+
- spec/connection_spec.rb
|
402
|
+
- spec/cookie_jar_spec.rb
|
403
|
+
- spec/driver_rendering_spec.rb
|
404
|
+
- spec/driver_resize_window_spec.rb
|
405
|
+
- spec/driver_spec.rb
|
406
|
+
- spec/errors_spec.rb
|
407
|
+
- spec/fixtures/exit_text.rb
|
408
|
+
- spec/fixtures/fake_server.sh
|
409
|
+
- spec/integration/session_spec.rb
|
410
|
+
- spec/node_spec.rb
|
411
|
+
- spec/selenium_compatibility_spec.rb
|
412
|
+
- spec/self_signed_ssl_cert.rb
|
413
|
+
- spec/server_spec.rb
|
414
|
+
- spec/spec_helper.rb
|
415
|
+
- spec/support/app_runner.rb
|
416
|
+
- spec/support/matchers/include_response.rb
|
417
|
+
- spec/support/output_writer.rb
|
data/gemfiles/2.13.gemfile
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "mime-types", "< 3.0", :platforms=>[:ruby_19, :jruby_19]
|
6
|
-
gem "json", "< 2.0", :platforms=>[:ruby_19, :jruby_19]
|
7
|
-
gem "capybara", "~> 2.13.0"
|
8
|
-
gem "addressable", "< 2.5.0", :platforms=>[:ruby_19, :jruby_19]
|
9
|
-
gem "nokogiri", "< 1.7.0", :platforms=>[:ruby_19, :jruby_19]
|
10
|
-
|
11
|
-
gemspec :path=>"../"
|