poltergeist 1.11.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/capybara/poltergeist/client.rb +13 -25
- data/lib/capybara/poltergeist/client/agent.coffee +1 -19
- data/lib/capybara/poltergeist/client/compiled/agent.js +4 -28
- data/lib/capybara/poltergeist/client/compiled/cmd.js +1 -1
- data/lib/capybara/poltergeist/client/compiled/web_page.js +96 -18
- data/lib/capybara/poltergeist/client/web_page.coffee +96 -16
- data/lib/capybara/poltergeist/version.rb +1 -1
- metadata +7 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62a6d774d0e6cf68f19667891d54f61c810e89f1
|
4
|
+
data.tar.gz: 19861cdfb3615834316772b64ee067be4efca384
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3caef6797f238771788a78b0db80019e0f5559c2aef822e3bd102682ecd88a12160e39f6cf6c8a6dd58a4771cb501911fb99ac06d6464f1b8f0370b5dabae9cf
|
7
|
+
data.tar.gz: ad4321b2d883e7e2236ca800d401371a863027abe9b9a2c6807ae93c16898c77c9284844366504bec5b9f66d93c3d9c55a546af3ae1a79552b3ebe907dd6cb0b
|
@@ -23,8 +23,19 @@ module Capybara::Poltergeist
|
|
23
23
|
def self.process_killer(pid)
|
24
24
|
proc do
|
25
25
|
begin
|
26
|
-
|
26
|
+
if Capybara::Poltergeist.windows?
|
27
|
+
Process.kill('KILL', pid)
|
28
|
+
else
|
29
|
+
Process.kill('TERM', pid)
|
30
|
+
begin
|
31
|
+
Timeout.timeout(KILL_TIMEOUT) { Process.wait(pid) }
|
32
|
+
rescue Timeout::Error
|
33
|
+
Process.kill('KILL', pid)
|
34
|
+
Process.wait(pid)
|
35
|
+
end
|
36
|
+
end
|
27
37
|
rescue Errno::ESRCH, Errno::ECHILD
|
38
|
+
# Zed's dead, baby
|
28
39
|
end
|
29
40
|
end
|
30
41
|
end
|
@@ -41,15 +52,6 @@ module Capybara::Poltergeist
|
|
41
52
|
@window_size = options[:window_size] || [1024, 768]
|
42
53
|
@phantomjs_options = options[:phantomjs_options] || []
|
43
54
|
@phantomjs_logger = options[:phantomjs_logger] || $stdout
|
44
|
-
|
45
|
-
pid = Process.pid
|
46
|
-
at_exit do
|
47
|
-
# do the work in a separate thread, to avoid stomping on $!,
|
48
|
-
# since other libraries depend on it directly.
|
49
|
-
Thread.new do
|
50
|
-
stop if Process.pid == pid
|
51
|
-
end.join
|
52
|
-
end
|
53
55
|
end
|
54
56
|
|
55
57
|
def start
|
@@ -111,21 +113,7 @@ module Capybara::Poltergeist
|
|
111
113
|
end
|
112
114
|
|
113
115
|
def kill_phantomjs
|
114
|
-
|
115
|
-
if Capybara::Poltergeist.windows?
|
116
|
-
Process.kill('KILL', pid)
|
117
|
-
else
|
118
|
-
Process.kill('TERM', pid)
|
119
|
-
begin
|
120
|
-
Timeout.timeout(KILL_TIMEOUT) { Process.wait(pid) }
|
121
|
-
rescue Timeout::Error
|
122
|
-
Process.kill('KILL', pid)
|
123
|
-
Process.wait(pid)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
rescue Errno::ESRCH, Errno::ECHILD
|
127
|
-
# Zed's dead, baby
|
128
|
-
end
|
116
|
+
self.class.process_killer(pid).call
|
129
117
|
@pid = nil
|
130
118
|
end
|
131
119
|
|
@@ -1,10 +1,5 @@
|
|
1
1
|
# This is injected into each page that is loaded
|
2
|
-
|
3
2
|
class PoltergeistAgent
|
4
|
-
# Since this code executes in the sites browser space - copy needed JSON functions
|
5
|
-
# in case user code messes with JSON (early mootools for instance)
|
6
|
-
@.JSON ||= { parse: JSON.parse, stringify: JSON.stringify }
|
7
|
-
|
8
3
|
constructor: ->
|
9
4
|
@elements = []
|
10
5
|
@nodes = {}
|
@@ -15,19 +10,6 @@ class PoltergeistAgent
|
|
15
10
|
catch error
|
16
11
|
{ error: { message: error.toString(), stack: error.stack } }
|
17
12
|
|
18
|
-
@stringify: (object) ->
|
19
|
-
try
|
20
|
-
PoltergeistAgent.JSON.stringify object, (key, value) ->
|
21
|
-
if Array.isArray(this[key])
|
22
|
-
return this[key]
|
23
|
-
else
|
24
|
-
return value
|
25
|
-
catch error
|
26
|
-
if error instanceof TypeError
|
27
|
-
'"(cyclic structure)"'
|
28
|
-
else
|
29
|
-
throw error
|
30
|
-
|
31
13
|
# Somehow PhantomJS returns all characters(brackets, etc) properly encoded
|
32
14
|
# except whitespace character in pathname part of the location. This hack
|
33
15
|
# is intended to fix this up.
|
@@ -194,7 +176,7 @@ class PoltergeistAgent.Node
|
|
194
176
|
if name == 'checked' || name == 'selected'
|
195
177
|
@element[name]
|
196
178
|
else
|
197
|
-
@element.getAttribute(name)
|
179
|
+
@element.getAttribute(name) ? undefined
|
198
180
|
|
199
181
|
scrollIntoView: ->
|
200
182
|
@element.scrollIntoViewIfNeeded()
|
@@ -1,18 +1,13 @@
|
|
1
1
|
var PoltergeistAgent;
|
2
2
|
|
3
3
|
PoltergeistAgent = (function() {
|
4
|
-
PoltergeistAgent.JSON || (PoltergeistAgent.JSON = {
|
5
|
-
parse: JSON.parse,
|
6
|
-
stringify: JSON.stringify
|
7
|
-
});
|
8
|
-
|
9
4
|
function PoltergeistAgent() {
|
10
5
|
this.elements = [];
|
11
6
|
this.nodes = {};
|
12
7
|
}
|
13
8
|
|
14
9
|
PoltergeistAgent.prototype.externalCall = function(name, args) {
|
15
|
-
var error
|
10
|
+
var error;
|
16
11
|
try {
|
17
12
|
return {
|
18
13
|
value: this[name].apply(this, args)
|
@@ -28,32 +23,12 @@ PoltergeistAgent = (function() {
|
|
28
23
|
}
|
29
24
|
};
|
30
25
|
|
31
|
-
PoltergeistAgent.stringify = function(object) {
|
32
|
-
var error, error1;
|
33
|
-
try {
|
34
|
-
return PoltergeistAgent.JSON.stringify(object, function(key, value) {
|
35
|
-
if (Array.isArray(this[key])) {
|
36
|
-
return this[key];
|
37
|
-
} else {
|
38
|
-
return value;
|
39
|
-
}
|
40
|
-
});
|
41
|
-
} catch (error1) {
|
42
|
-
error = error1;
|
43
|
-
if (error instanceof TypeError) {
|
44
|
-
return '"(cyclic structure)"';
|
45
|
-
} else {
|
46
|
-
throw error;
|
47
|
-
}
|
48
|
-
}
|
49
|
-
};
|
50
|
-
|
51
26
|
PoltergeistAgent.prototype.currentUrl = function() {
|
52
27
|
return window.location.href.replace(/\ /g, '%20');
|
53
28
|
};
|
54
29
|
|
55
30
|
PoltergeistAgent.prototype.find = function(method, selector, within) {
|
56
|
-
var el, error,
|
31
|
+
var el, error, i, j, len, results, results1, xpath;
|
57
32
|
if (within == null) {
|
58
33
|
within = document;
|
59
34
|
}
|
@@ -296,10 +271,11 @@ PoltergeistAgent.Node = (function() {
|
|
296
271
|
};
|
297
272
|
|
298
273
|
Node.prototype.getAttribute = function(name) {
|
274
|
+
var ref;
|
299
275
|
if (name === 'checked' || name === 'selected') {
|
300
276
|
return this.element[name];
|
301
277
|
} else {
|
302
|
-
return this.element.getAttribute(name);
|
278
|
+
return (ref = this.element.getAttribute(name)) != null ? ref : void 0;
|
303
279
|
}
|
304
280
|
};
|
305
281
|
|
@@ -28,11 +28,15 @@ Poltergeist.WebPage = (function() {
|
|
28
28
|
this._tempHeaders = {};
|
29
29
|
this._blockedUrls = [];
|
30
30
|
this._requestedResources = {};
|
31
|
+
this._responseHeaders = [];
|
31
32
|
ref = WebPage.CALLBACKS;
|
32
33
|
for (i = 0, len = ref.length; i < len; i++) {
|
33
34
|
callback = ref[i];
|
34
35
|
this.bindCallback(callback);
|
35
36
|
}
|
37
|
+
if (phantom.version.major < 2) {
|
38
|
+
this._overrideNativeEvaluate();
|
39
|
+
}
|
36
40
|
}
|
37
41
|
|
38
42
|
ref = WebPage.COMMANDS;
|
@@ -498,32 +502,20 @@ Poltergeist.WebPage = (function() {
|
|
498
502
|
};
|
499
503
|
|
500
504
|
WebPage.prototype.evaluate = function() {
|
501
|
-
var args, fn;
|
505
|
+
var args, fn, ref2;
|
502
506
|
fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
503
507
|
this.injectAgent();
|
504
|
-
return
|
505
|
-
};
|
506
|
-
|
507
|
-
WebPage.prototype.sanitize = function(potential_string) {
|
508
|
-
if (typeof potential_string === "string") {
|
509
|
-
return potential_string.replace("\n", "\\n").replace("\r", "\\r");
|
510
|
-
} else {
|
511
|
-
return potential_string;
|
512
|
-
}
|
508
|
+
return (ref2 = this["native"]()).evaluate.apply(ref2, ["function() { var _result = " + (this.stringifyCall(fn)) + "; return (_result == null) ? undefined : _result; }"].concat(slice.call(args)));
|
513
509
|
};
|
514
510
|
|
515
511
|
WebPage.prototype.execute = function() {
|
516
|
-
var args, fn;
|
512
|
+
var args, fn, ref2;
|
517
513
|
fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
518
|
-
return this["native"]().evaluate("function() { " + (this.stringifyCall(fn
|
514
|
+
return (ref2 = this["native"]()).evaluate.apply(ref2, ["function() { " + (this.stringifyCall(fn)) + " }"].concat(slice.call(args)));
|
519
515
|
};
|
520
516
|
|
521
|
-
WebPage.prototype.stringifyCall = function(fn
|
522
|
-
|
523
|
-
return "(" + (fn.toString()) + ")()";
|
524
|
-
} else {
|
525
|
-
return "(" + (fn.toString()) + ").apply(this, PoltergeistAgent.JSON.parse(" + (JSON.stringify(JSON.stringify(args))) + "))";
|
526
|
-
}
|
517
|
+
WebPage.prototype.stringifyCall = function(fn) {
|
518
|
+
return "(" + (fn.toString()) + ").apply(this, arguments)";
|
527
519
|
};
|
528
520
|
|
529
521
|
WebPage.prototype.bindCallback = function(name) {
|
@@ -590,6 +582,92 @@ Poltergeist.WebPage = (function() {
|
|
590
582
|
}
|
591
583
|
};
|
592
584
|
|
585
|
+
WebPage.prototype._overrideNativeEvaluate = function() {
|
586
|
+
return this._native.evaluate = function (func, args) {
|
587
|
+
function quoteString(str) {
|
588
|
+
var c, i, l = str.length, o = '"';
|
589
|
+
for (i = 0; i < l; i += 1) {
|
590
|
+
c = str.charAt(i);
|
591
|
+
if (c >= ' ') {
|
592
|
+
if (c === '\\' || c === '"') {
|
593
|
+
o += '\\';
|
594
|
+
}
|
595
|
+
o += c;
|
596
|
+
} else {
|
597
|
+
switch (c) {
|
598
|
+
case '\b':
|
599
|
+
o += '\\b';
|
600
|
+
break;
|
601
|
+
case '\f':
|
602
|
+
o += '\\f';
|
603
|
+
break;
|
604
|
+
case '\n':
|
605
|
+
o += '\\n';
|
606
|
+
break;
|
607
|
+
case '\r':
|
608
|
+
o += '\\r';
|
609
|
+
break;
|
610
|
+
case '\t':
|
611
|
+
o += '\\t';
|
612
|
+
break;
|
613
|
+
default:
|
614
|
+
c = c.charCodeAt();
|
615
|
+
o += '\\u00' + Math.floor(c / 16).toString(16) +
|
616
|
+
(c % 16).toString(16);
|
617
|
+
}
|
618
|
+
}
|
619
|
+
}
|
620
|
+
return o + '"';
|
621
|
+
}
|
622
|
+
|
623
|
+
function detectType(value) {
|
624
|
+
var s = typeof value;
|
625
|
+
if (s === 'object') {
|
626
|
+
if (value) {
|
627
|
+
if (value instanceof Array) {
|
628
|
+
s = 'array';
|
629
|
+
} else if (value instanceof RegExp) {
|
630
|
+
s = 'regexp';
|
631
|
+
} else if (value instanceof Date) {
|
632
|
+
s = 'date';
|
633
|
+
}
|
634
|
+
} else {
|
635
|
+
s = 'null';
|
636
|
+
}
|
637
|
+
}
|
638
|
+
return s;
|
639
|
+
}
|
640
|
+
|
641
|
+
var str, arg, argType, i, l;
|
642
|
+
if (!(func instanceof Function || typeof func === 'string' || func instanceof String)) {
|
643
|
+
throw "Wrong use of WebPage#evaluate";
|
644
|
+
}
|
645
|
+
str = 'function() { return (' + func.toString() + ')(';
|
646
|
+
for (i = 1, l = arguments.length; i < l; i++) {
|
647
|
+
arg = arguments[i];
|
648
|
+
argType = detectType(arg);
|
649
|
+
|
650
|
+
switch (argType) {
|
651
|
+
case "object": //< for type "object"
|
652
|
+
case "array": //< for type "array"
|
653
|
+
str += JSON.stringify(arg) + ","
|
654
|
+
break;
|
655
|
+
case "date": //< for type "date"
|
656
|
+
str += "new Date(" + JSON.stringify(arg) + "),"
|
657
|
+
break;
|
658
|
+
case "string": //< for type "string"
|
659
|
+
str += quoteString(arg) + ',';
|
660
|
+
break;
|
661
|
+
default: // for types: "null", "number", "function", "regexp", "undefined"
|
662
|
+
str += arg + ',';
|
663
|
+
break;
|
664
|
+
}
|
665
|
+
}
|
666
|
+
str = str.replace(/,$/, '') + '); }';
|
667
|
+
return this.evaluateJavaScript(str);
|
668
|
+
};;
|
669
|
+
};
|
670
|
+
|
593
671
|
return WebPage;
|
594
672
|
|
595
673
|
})();
|
@@ -27,10 +27,14 @@ class Poltergeist.WebPage
|
|
27
27
|
@_tempHeaders = {}
|
28
28
|
@_blockedUrls = []
|
29
29
|
@_requestedResources = {}
|
30
|
+
@_responseHeaders = []
|
30
31
|
|
31
32
|
for callback in WebPage.CALLBACKS
|
32
33
|
this.bindCallback(callback)
|
33
34
|
|
35
|
+
if phantom.version.major < 2
|
36
|
+
@._overrideNativeEvaluate()
|
37
|
+
|
34
38
|
for command in @COMMANDS
|
35
39
|
do (command) =>
|
36
40
|
this.prototype[command] =
|
@@ -341,25 +345,14 @@ class Poltergeist.WebPage
|
|
341
345
|
|
342
346
|
evaluate: (fn, args...) ->
|
343
347
|
this.injectAgent()
|
344
|
-
|
345
|
-
|
346
|
-
sanitize: (potential_string) ->
|
347
|
-
if typeof(potential_string) == "string"
|
348
|
-
# JSON doesn't like \r or \n in strings unless escaped
|
349
|
-
potential_string.replace("\n","\\n").replace("\r","\\r")
|
350
|
-
else
|
351
|
-
potential_string
|
348
|
+
this.native().evaluate("function() { var _result = #{this.stringifyCall(fn)};
|
349
|
+
return (_result == null) ? undefined : _result; }", args...)
|
352
350
|
|
353
351
|
execute: (fn, args...) ->
|
354
|
-
this.native().evaluate("function() { #{this.stringifyCall(fn
|
352
|
+
this.native().evaluate("function() { #{this.stringifyCall(fn)} }", args...)
|
355
353
|
|
356
|
-
stringifyCall: (fn
|
357
|
-
|
358
|
-
"(#{fn.toString()})()"
|
359
|
-
else
|
360
|
-
# The JSON.stringify happens twice because the second time we are essentially
|
361
|
-
# escaping the string.
|
362
|
-
"(#{fn.toString()}).apply(this, PoltergeistAgent.JSON.parse(#{JSON.stringify(JSON.stringify(args))}))"
|
354
|
+
stringifyCall: (fn) ->
|
355
|
+
"(#{fn.toString()}).apply(this, arguments)"
|
363
356
|
|
364
357
|
bindCallback: (name) ->
|
365
358
|
@native()[name] = =>
|
@@ -406,3 +399,90 @@ class Poltergeist.WebPage
|
|
406
399
|
clearMemoryCache()
|
407
400
|
else
|
408
401
|
throw new Poltergeist.UnsupportedFeature("clearMemoryCache is supported since PhantomJS 2.0.0")
|
402
|
+
|
403
|
+
_overrideNativeEvaluate: ->
|
404
|
+
# PhantomJS 1.9.x WebPage#evaluate depends on the browser context JSON, this replaces it
|
405
|
+
# with the evaluate from 2.1.1 which uses the PhantomJS JSON
|
406
|
+
@_native.evaluate = `function (func, args) {
|
407
|
+
function quoteString(str) {
|
408
|
+
var c, i, l = str.length, o = '"';
|
409
|
+
for (i = 0; i < l; i += 1) {
|
410
|
+
c = str.charAt(i);
|
411
|
+
if (c >= ' ') {
|
412
|
+
if (c === '\\' || c === '"') {
|
413
|
+
o += '\\';
|
414
|
+
}
|
415
|
+
o += c;
|
416
|
+
} else {
|
417
|
+
switch (c) {
|
418
|
+
case '\b':
|
419
|
+
o += '\\b';
|
420
|
+
break;
|
421
|
+
case '\f':
|
422
|
+
o += '\\f';
|
423
|
+
break;
|
424
|
+
case '\n':
|
425
|
+
o += '\\n';
|
426
|
+
break;
|
427
|
+
case '\r':
|
428
|
+
o += '\\r';
|
429
|
+
break;
|
430
|
+
case '\t':
|
431
|
+
o += '\\t';
|
432
|
+
break;
|
433
|
+
default:
|
434
|
+
c = c.charCodeAt();
|
435
|
+
o += '\\u00' + Math.floor(c / 16).toString(16) +
|
436
|
+
(c % 16).toString(16);
|
437
|
+
}
|
438
|
+
}
|
439
|
+
}
|
440
|
+
return o + '"';
|
441
|
+
}
|
442
|
+
|
443
|
+
function detectType(value) {
|
444
|
+
var s = typeof value;
|
445
|
+
if (s === 'object') {
|
446
|
+
if (value) {
|
447
|
+
if (value instanceof Array) {
|
448
|
+
s = 'array';
|
449
|
+
} else if (value instanceof RegExp) {
|
450
|
+
s = 'regexp';
|
451
|
+
} else if (value instanceof Date) {
|
452
|
+
s = 'date';
|
453
|
+
}
|
454
|
+
} else {
|
455
|
+
s = 'null';
|
456
|
+
}
|
457
|
+
}
|
458
|
+
return s;
|
459
|
+
}
|
460
|
+
|
461
|
+
var str, arg, argType, i, l;
|
462
|
+
if (!(func instanceof Function || typeof func === 'string' || func instanceof String)) {
|
463
|
+
throw "Wrong use of WebPage#evaluate";
|
464
|
+
}
|
465
|
+
str = 'function() { return (' + func.toString() + ')(';
|
466
|
+
for (i = 1, l = arguments.length; i < l; i++) {
|
467
|
+
arg = arguments[i];
|
468
|
+
argType = detectType(arg);
|
469
|
+
|
470
|
+
switch (argType) {
|
471
|
+
case "object": //< for type "object"
|
472
|
+
case "array": //< for type "array"
|
473
|
+
str += JSON.stringify(arg) + ","
|
474
|
+
break;
|
475
|
+
case "date": //< for type "date"
|
476
|
+
str += "new Date(" + JSON.stringify(arg) + "),"
|
477
|
+
break;
|
478
|
+
case "string": //< for type "string"
|
479
|
+
str += quoteString(arg) + ',';
|
480
|
+
break;
|
481
|
+
default: // for types: "null", "number", "function", "regexp", "undefined"
|
482
|
+
str += arg + ',';
|
483
|
+
break;
|
484
|
+
}
|
485
|
+
}
|
486
|
+
str = str.replace(/,$/, '') + '); }';
|
487
|
+
return this.evaluateJavaScript(str);
|
488
|
+
};`
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poltergeist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Leighton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|
@@ -72,28 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 3.
|
75
|
+
version: 3.5.0
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 3.
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec-core
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "!="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 3.4.0
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "!="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 3.4.0
|
82
|
+
version: 3.5.0
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: sinatra
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,14 +176,14 @@ dependencies:
|
|
190
176
|
requirements:
|
191
177
|
- - "~>"
|
192
178
|
- !ruby/object:Gem::Version
|
193
|
-
version: 1.
|
179
|
+
version: 1.11.1
|
194
180
|
type: :development
|
195
181
|
prerelease: false
|
196
182
|
version_requirements: !ruby/object:Gem::Requirement
|
197
183
|
requirements:
|
198
184
|
- - "~>"
|
199
185
|
- !ruby/object:Gem::Version
|
200
|
-
version: 1.
|
186
|
+
version: 1.11.1
|
201
187
|
- !ruby/object:Gem::Dependency
|
202
188
|
name: listen
|
203
189
|
requirement: !ruby/object:Gem::Requirement
|
@@ -287,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
287
273
|
version: '0'
|
288
274
|
requirements: []
|
289
275
|
rubyforge_project:
|
290
|
-
rubygems_version: 2.5.
|
276
|
+
rubygems_version: 2.5.2
|
291
277
|
signing_key:
|
292
278
|
specification_version: 4
|
293
279
|
summary: PhantomJS driver for Capybara
|