capybara-webkit 0.12.1 → 0.13.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/.gitignore +2 -1
- data/GOALS +9 -0
- data/Gemfile.lock +15 -12
- data/LICENSE +1 -1
- data/NEWS.md +18 -0
- data/README.md +81 -2
- data/capybara-webkit.gemspec +1 -1
- data/lib/capybara/webkit.rb +11 -6
- data/lib/capybara/{driver/webkit → webkit}/browser.rb +90 -4
- data/lib/capybara/{driver/webkit → webkit}/connection.rb +48 -47
- data/lib/capybara/{driver/webkit → webkit}/cookie_jar.rb +1 -1
- data/lib/capybara/webkit/driver.rb +186 -0
- data/lib/capybara/webkit/errors.rb +10 -0
- data/lib/capybara/{driver/webkit → webkit}/node.rb +12 -4
- data/lib/capybara/{driver/webkit → webkit}/socket_debugger.rb +4 -1
- data/lib/capybara/{driver/webkit → webkit}/version.rb +1 -1
- data/lib/capybara_webkit_builder.rb +17 -3
- data/spec/browser_spec.rb +95 -7
- data/spec/connection_spec.rb +16 -5
- data/spec/cookie_jar_spec.rb +3 -3
- data/spec/driver_rendering_spec.rb +19 -26
- data/spec/driver_resize_window_spec.rb +3 -3
- data/spec/driver_spec.rb +1200 -822
- data/spec/integration/driver_spec.rb +4 -3
- data/spec/selenium_compatibility_spec.rb +49 -0
- data/spec/spec_helper.rb +14 -6
- data/spec/support/app_runner.rb +94 -0
- data/src/Authenticate.cpp +18 -0
- data/src/Authenticate.h +12 -0
- data/src/Body.h +3 -5
- data/src/ClearCookies.cpp +3 -5
- data/src/ClearCookies.h +3 -5
- data/src/ClearPromptText.cpp +11 -0
- data/src/ClearPromptText.h +9 -0
- data/src/Command.cpp +4 -15
- data/src/Command.h +3 -14
- data/src/CommandFactory.cpp +20 -6
- data/src/CommandFactory.h +3 -2
- data/src/CommandParser.cpp +1 -1
- data/src/Connection.cpp +22 -21
- data/src/Connection.h +5 -6
- data/src/ConsoleMessages.cpp +2 -1
- data/src/ConsoleMessages.h +3 -5
- data/src/CurrentUrl.cpp +9 -48
- data/src/CurrentUrl.h +8 -8
- data/src/EnableLogging.cpp +10 -0
- data/src/EnableLogging.h +12 -0
- data/src/Evaluate.cpp +2 -1
- data/src/Evaluate.h +3 -5
- data/src/Execute.cpp +2 -1
- data/src/Execute.h +3 -5
- data/src/Find.cpp +3 -2
- data/src/Find.h +3 -5
- data/src/FrameFocus.cpp +3 -2
- data/src/FrameFocus.h +3 -4
- data/src/GetCookies.cpp +3 -4
- data/src/GetCookies.h +3 -5
- data/src/GetTimeout.cpp +9 -0
- data/src/GetTimeout.h +11 -0
- data/src/GetWindowHandle.cpp +11 -0
- data/src/GetWindowHandle.h +10 -0
- data/src/GetWindowHandles.cpp +20 -0
- data/src/GetWindowHandles.h +10 -0
- data/src/Header.cpp +2 -1
- data/src/Header.h +3 -5
- data/src/Headers.cpp +8 -2
- data/src/Headers.h +3 -5
- data/src/IgnoreSslErrors.cpp +4 -3
- data/src/IgnoreSslErrors.h +3 -5
- data/src/JavascriptAlertMessages.cpp +10 -0
- data/src/JavascriptAlertMessages.h +9 -0
- data/src/JavascriptConfirmMessages.cpp +10 -0
- data/src/JavascriptConfirmMessages.h +9 -0
- data/src/JavascriptInvocation.cpp +1 -1
- data/src/JavascriptInvocation.h +1 -1
- data/src/JavascriptPromptMessages.cpp +10 -0
- data/src/JavascriptPromptMessages.h +9 -0
- data/src/NetworkAccessManager.cpp +38 -5
- data/src/NetworkAccessManager.h +20 -0
- data/src/Node.cpp +6 -1
- data/src/Node.h +4 -5
- data/src/NullCommand.cpp +5 -2
- data/src/NullCommand.h +4 -3
- data/src/PageLoadingCommand.cpp +12 -7
- data/src/PageLoadingCommand.h +6 -9
- data/src/Render.cpp +2 -1
- data/src/Render.h +3 -5
- data/src/RequestedUrl.cpp +2 -1
- data/src/RequestedUrl.h +3 -5
- data/src/Reset.cpp +3 -17
- data/src/Reset.h +3 -8
- data/src/ResizeWindow.cpp +2 -1
- data/src/ResizeWindow.h +3 -5
- data/src/Response.cpp +4 -0
- data/src/Response.h +1 -0
- data/src/Server.cpp +2 -3
- data/src/Server.h +0 -2
- data/src/SetConfirmAction.cpp +11 -0
- data/src/SetConfirmAction.h +9 -0
- data/src/SetCookie.cpp +3 -4
- data/src/SetCookie.h +3 -5
- data/src/SetPromptAction.cpp +11 -0
- data/src/SetPromptAction.h +9 -0
- data/src/SetPromptText.cpp +11 -0
- data/src/SetPromptText.h +9 -0
- data/src/SetProxy.cpp +2 -1
- data/src/SetProxy.h +3 -5
- data/src/SetSkipImageLoading.cpp +12 -0
- data/src/SetSkipImageLoading.h +9 -0
- data/src/SetTimeout.cpp +19 -0
- data/src/SetTimeout.h +9 -0
- data/src/SocketCommand.cpp +21 -0
- data/src/SocketCommand.h +29 -0
- data/src/Source.cpp +3 -2
- data/src/Source.h +3 -4
- data/src/Status.cpp +2 -1
- data/src/Status.h +3 -5
- data/src/TimeoutCommand.cpp +69 -0
- data/src/TimeoutCommand.h +41 -0
- data/src/UnsupportedContentHandler.cpp +11 -17
- data/src/UnsupportedContentHandler.h +5 -3
- data/src/Url.cpp +2 -1
- data/src/Url.h +3 -5
- data/src/Visit.cpp +3 -2
- data/src/Visit.h +3 -5
- data/src/WebPage.cpp +129 -44
- data/src/WebPage.h +37 -11
- data/src/WebPageManager.cpp +127 -0
- data/src/WebPageManager.h +59 -0
- data/src/WindowFocus.cpp +32 -0
- data/src/WindowFocus.h +15 -0
- data/src/body.cpp +2 -1
- data/src/capybara.js +38 -10
- data/src/find_command.h +17 -2
- data/src/main.cpp +0 -2
- data/src/webkit_server.pro +36 -0
- data/templates/Command.cpp +2 -4
- data/templates/Command.h +3 -3
- metadata +106 -27
- data/ChangeLog +0 -70
- data/lib/capybara/driver/webkit.rb +0 -136
data/.gitignore
CHANGED
data/GOALS
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
capybara-webkit hits 1.0.0 when:
|
2
|
+
|
3
|
+
* All shared examples from capybara are implemented. See
|
4
|
+
capybara:lib/capybara/spec/**/*rb for the shared example groups.
|
5
|
+
* Test failures are a result of issues in the developer's code and not
|
6
|
+
capybara-webkit.
|
7
|
+
* Test failures lead to clear explanations for what failed and what can
|
8
|
+
be done to resolve them.
|
9
|
+
* It handles iframes, cookies, page loading, and other oddities.
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
capybara-webkit (0.
|
4
|
+
capybara-webkit (0.13.0)
|
5
5
|
capybara (>= 1.0.0, < 1.2)
|
6
6
|
json
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
+
addressable (2.3.2)
|
11
12
|
appraisal (0.4.0)
|
12
13
|
bundler
|
13
14
|
rake
|
@@ -18,18 +19,20 @@ GEM
|
|
18
19
|
rack-test (>= 0.5.4)
|
19
20
|
selenium-webdriver (~> 2.0)
|
20
21
|
xpath (~> 0.1.4)
|
21
|
-
childprocess (0.3.
|
22
|
-
ffi (~> 1.0.6)
|
22
|
+
childprocess (0.3.6)
|
23
|
+
ffi (~> 1.0, >= 1.0.6)
|
23
24
|
diff-lcs (1.1.2)
|
24
|
-
ffi (1.
|
25
|
-
json (1.7.
|
26
|
-
|
25
|
+
ffi (1.1.5)
|
26
|
+
json (1.7.5)
|
27
|
+
libwebsocket (0.1.5)
|
28
|
+
addressable
|
29
|
+
mime-types (1.19)
|
27
30
|
mini_magick (3.2.1)
|
28
31
|
subexec (~> 0.0.4)
|
29
|
-
multi_json (1.3.
|
30
|
-
nokogiri (1.5.
|
32
|
+
multi_json (1.3.6)
|
33
|
+
nokogiri (1.5.5)
|
31
34
|
rack (1.3.2)
|
32
|
-
rack-test (0.6.
|
35
|
+
rack-test (0.6.2)
|
33
36
|
rack (>= 1.0)
|
34
37
|
rake (0.9.2)
|
35
38
|
rspec (2.6.0)
|
@@ -40,10 +43,10 @@ GEM
|
|
40
43
|
rspec-expectations (2.6.0)
|
41
44
|
diff-lcs (~> 1.1.2)
|
42
45
|
rspec-mocks (2.6.0)
|
43
|
-
rubyzip (0.9.
|
44
|
-
selenium-webdriver (2.
|
46
|
+
rubyzip (0.9.9)
|
47
|
+
selenium-webdriver (2.25.0)
|
45
48
|
childprocess (>= 0.2.5)
|
46
|
-
|
49
|
+
libwebsocket (~> 0.1.3)
|
47
50
|
multi_json (~> 1.0)
|
48
51
|
rubyzip
|
49
52
|
sinatra (1.1.2)
|
data/LICENSE
CHANGED
data/NEWS.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
New for HEAD:
|
2
|
+
|
3
|
+
* Better detect page load success, and better handle load failures.
|
4
|
+
* HTTP Basic Auth support.
|
5
|
+
* within_window support.
|
6
|
+
* More useful and detailed debugging output.
|
7
|
+
* Catch up with recent capybara releases.
|
8
|
+
* Ignore errors from canceled requests.
|
9
|
+
* Follow how Selenium treats focus and blur form events.
|
10
|
+
* Control JavaScript prompts from Ruby.
|
11
|
+
* Each command has a configurable timeout.
|
12
|
+
* Performance improvements on Linux.
|
13
|
+
* Support empty `multiple` attributes.
|
14
|
+
|
15
|
+
New for 0.12.1:
|
16
|
+
|
17
|
+
* Fix integration with newer capybara for the debugging driver.
|
18
|
+
|
1
19
|
New for 0.12.0:
|
2
20
|
* Better windows support
|
3
21
|
* Support for localStorage
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
capybara-webkit
|
2
2
|
===============
|
3
3
|
|
4
|
+
[](https://codeclimate.com/github/thoughtbot/capybara-webkit)
|
5
|
+
|
4
6
|
A [capybara](https://github.com/jnicklas/capybara) driver that uses [WebKit](http://webkit.org) via [QtWebKit](http://doc.qt.nokia.com/4.7/qtwebkit.html).
|
5
7
|
|
6
8
|
Qt Dependency and Installation Issues
|
@@ -51,7 +53,7 @@ Set your Capybara Javascript driver to webkit:
|
|
51
53
|
|
52
54
|
In cucumber, tag scenarios with @javascript to run them using a headless WebKit browser.
|
53
55
|
|
54
|
-
In RSpec, use the :js => true flag.
|
56
|
+
In RSpec, use the :js => true flag. See the [capybara documention](http://rubydoc.info/gems/capybara#Using_Capybara_with_RSpec) for more information about using capybara with RSpec.
|
55
57
|
|
56
58
|
Take note of the transactional fixtures section of the [capybara README](https://github.com/jnicklas/capybara/blob/master/README.md).
|
57
59
|
|
@@ -77,6 +79,20 @@ capybara-webkit supports a few methods that are not part of the standard capybar
|
|
77
79
|
page.driver.error_messages
|
78
80
|
=> {:source=>"http://example.com", :line_number=>1, :message=>"SyntaxError: Parse error"}
|
79
81
|
|
82
|
+
**alert_messages, confirm_messages, prompt_messages**: returns arrays of Javascript dialog messages for each dialog type
|
83
|
+
|
84
|
+
# In Javascript:
|
85
|
+
alert("HI");
|
86
|
+
confirm("Ok?");
|
87
|
+
prompt("Number?", "42");
|
88
|
+
# In Ruby:
|
89
|
+
page.driver.alert_messages
|
90
|
+
=> ["Hi"]
|
91
|
+
page.driver.confirm_messages
|
92
|
+
=> ["Ok?"]
|
93
|
+
page.driver.prompt_messages
|
94
|
+
=> ["Number?"]
|
95
|
+
|
80
96
|
**resize_window**: change the viewport size to the given width and height
|
81
97
|
|
82
98
|
page.driver.resize_window(500, 300)
|
@@ -92,6 +108,69 @@ capybara-webkit supports a few methods that are not part of the standard capybar
|
|
92
108
|
page.driver.cookies["alpha"]
|
93
109
|
=> "abc"
|
94
110
|
|
111
|
+
**accept_js_confirms!**: accept any Javascript confirm that is triggered by the page's Javascript
|
112
|
+
|
113
|
+
# In Javascript:
|
114
|
+
if (confirm("Ok?"))
|
115
|
+
console.log("Hi");
|
116
|
+
else
|
117
|
+
console.log("Bye");
|
118
|
+
# In Ruby:
|
119
|
+
page.driver.accept_js_confirms!
|
120
|
+
visit "/"
|
121
|
+
page.driver.console_messages.first[:message]
|
122
|
+
=> "Hi"
|
123
|
+
|
124
|
+
**dismiss_js_confirms!**: dismiss any Javascript confirm that is triggered by the page's Javascript
|
125
|
+
|
126
|
+
# In Javascript:
|
127
|
+
if (confirm("Ok?"))
|
128
|
+
console.log("Hi");
|
129
|
+
else
|
130
|
+
console.log("Bye");
|
131
|
+
# In Ruby:
|
132
|
+
page.driver.dismiss_js_confirms!
|
133
|
+
visit "/"
|
134
|
+
page.driver.console_messages.first[:message]
|
135
|
+
=> "Bye"
|
136
|
+
|
137
|
+
**accept_js_prompts!**: accept any Javascript prompt that is triggered by the page's Javascript
|
138
|
+
|
139
|
+
# In Javascript:
|
140
|
+
var a = prompt("Number?", "0")
|
141
|
+
console.log(a);
|
142
|
+
# In Ruby:
|
143
|
+
page.driver.accept_js_prompts!
|
144
|
+
visit "/"
|
145
|
+
page.driver.console_messages.first[:message]
|
146
|
+
=> "0"
|
147
|
+
|
148
|
+
**dismiss_js_prompts!**: dismiss any Javascript prompt that is triggered by the page's Javascript
|
149
|
+
|
150
|
+
# In Javascript:
|
151
|
+
var a = prompt("Number?", "0")
|
152
|
+
if (a != null)
|
153
|
+
console.log(a);
|
154
|
+
else
|
155
|
+
console.log("you said no"));
|
156
|
+
# In Ruby:
|
157
|
+
page.driver.dismiss_js_prompts!
|
158
|
+
visit "/"
|
159
|
+
page.driver.console_messages.first[:message]
|
160
|
+
=> "you said no"
|
161
|
+
|
162
|
+
**js_prompt_input=(value)**: set the text to use if a Javascript prompt is encountered and accepted
|
163
|
+
|
164
|
+
# In Javascript:
|
165
|
+
var a = prompt("Number?", "0")
|
166
|
+
console.log(a);
|
167
|
+
# In Ruby:
|
168
|
+
page.driver.js_prompt_input = "42"
|
169
|
+
page.driver.accept_js_prompts!
|
170
|
+
visit "/"
|
171
|
+
page.driver.console_messages.first[:message]
|
172
|
+
=> "42"
|
173
|
+
|
95
174
|
Contributing
|
96
175
|
------------
|
97
176
|
|
@@ -111,4 +190,4 @@ The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
|
111
190
|
License
|
112
191
|
-------
|
113
192
|
|
114
|
-
capybara-webkit is Copyright (c)
|
193
|
+
capybara-webkit is Copyright (c) 2010-2012 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
data/capybara-webkit.gemspec
CHANGED
data/lib/capybara/webkit.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
require "capybara"
|
2
|
-
|
2
|
+
|
3
|
+
module Capybara
|
4
|
+
module Webkit
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
require "capybara/webkit/driver"
|
3
9
|
|
4
10
|
Capybara.register_driver :webkit do |app|
|
5
|
-
Capybara::Driver
|
11
|
+
Capybara::Webkit::Driver.new(app)
|
6
12
|
end
|
7
13
|
|
8
14
|
Capybara.register_driver :webkit_debug do |app|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Capybara::Driver::Webkit.new(app, :browser => browser)
|
15
|
+
driver = Capybara::Webkit::Driver.new(app)
|
16
|
+
driver.enable_logging
|
17
|
+
driver
|
13
18
|
end
|
@@ -1,11 +1,19 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
|
-
|
3
|
+
module Capybara::Webkit
|
4
4
|
class Browser
|
5
5
|
def initialize(connection)
|
6
6
|
@connection = connection
|
7
7
|
end
|
8
8
|
|
9
|
+
def authenticate(username, password)
|
10
|
+
command("Authenticate", username, password)
|
11
|
+
end
|
12
|
+
|
13
|
+
def enable_logging
|
14
|
+
command "EnableLogging"
|
15
|
+
end
|
16
|
+
|
9
17
|
def visit(url)
|
10
18
|
command "Visit", url
|
11
19
|
end
|
@@ -47,6 +55,18 @@ class Capybara::Driver::Webkit
|
|
47
55
|
end
|
48
56
|
end
|
49
57
|
|
58
|
+
def alert_messages
|
59
|
+
command("JavascriptAlertMessages").split("\n")
|
60
|
+
end
|
61
|
+
|
62
|
+
def confirm_messages
|
63
|
+
command("JavascriptConfirmMessages").split("\n")
|
64
|
+
end
|
65
|
+
|
66
|
+
def prompt_messages
|
67
|
+
command("JavascriptPromptMessages").split("\n")
|
68
|
+
end
|
69
|
+
|
50
70
|
def response_headers
|
51
71
|
Hash[command("Headers").split("\n").map { |header| header.split(": ") }]
|
52
72
|
end
|
@@ -77,6 +97,50 @@ class Capybara::Driver::Webkit
|
|
77
97
|
command("IgnoreSslErrors")
|
78
98
|
end
|
79
99
|
|
100
|
+
def set_skip_image_loading(skip_image_loading)
|
101
|
+
command("SetSkipImageLoading", skip_image_loading)
|
102
|
+
end
|
103
|
+
|
104
|
+
def window_focus(selector)
|
105
|
+
command("WindowFocus", selector)
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_window_handles
|
109
|
+
JSON.parse(command('GetWindowHandles'))
|
110
|
+
end
|
111
|
+
|
112
|
+
alias_method :window_handles, :get_window_handles
|
113
|
+
|
114
|
+
def get_window_handle
|
115
|
+
command('GetWindowHandle')
|
116
|
+
end
|
117
|
+
|
118
|
+
alias_method :window_handle, :get_window_handle
|
119
|
+
|
120
|
+
def accept_js_confirms
|
121
|
+
command("SetConfirmAction", "Yes")
|
122
|
+
end
|
123
|
+
|
124
|
+
def reject_js_confirms
|
125
|
+
command("SetConfirmAction", "No")
|
126
|
+
end
|
127
|
+
|
128
|
+
def accept_js_prompts
|
129
|
+
command("SetPromptAction", "Yes")
|
130
|
+
end
|
131
|
+
|
132
|
+
def reject_js_prompts
|
133
|
+
command("SetPromptAction", "No")
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_prompt_text_to(string)
|
137
|
+
command("SetPromptText", string)
|
138
|
+
end
|
139
|
+
|
140
|
+
def clear_prompt_text
|
141
|
+
command("ClearPromptText")
|
142
|
+
end
|
143
|
+
|
80
144
|
def command(name, *args)
|
81
145
|
@connection.puts name
|
82
146
|
@connection.puts args.size
|
@@ -101,6 +165,14 @@ class Capybara::Driver::Webkit
|
|
101
165
|
command "Render", path, width, height
|
102
166
|
end
|
103
167
|
|
168
|
+
def timeout=(timeout_in_seconds)
|
169
|
+
command "SetTimeout", timeout_in_seconds
|
170
|
+
end
|
171
|
+
|
172
|
+
def timeout
|
173
|
+
command("GetTimeout").to_i
|
174
|
+
end
|
175
|
+
|
104
176
|
def set_cookie(cookie)
|
105
177
|
command "SetCookie", cookie
|
106
178
|
end
|
@@ -133,14 +205,28 @@ class Capybara::Driver::Webkit
|
|
133
205
|
result.strip! if result
|
134
206
|
|
135
207
|
if result.nil?
|
136
|
-
raise
|
137
|
-
elsif result != 'ok'
|
138
|
-
|
208
|
+
raise NoResponseError, "No response received from the server."
|
209
|
+
elsif result != 'ok'
|
210
|
+
case response = read_response
|
211
|
+
when "timeout"
|
212
|
+
raise Capybara::TimeoutError, "Request timed out after #{timeout_seconds}"
|
213
|
+
else
|
214
|
+
raise InvalidResponseError, response
|
215
|
+
end
|
139
216
|
end
|
140
217
|
|
141
218
|
result
|
142
219
|
end
|
143
220
|
|
221
|
+
def timeout_seconds
|
222
|
+
seconds = timeout
|
223
|
+
if seconds > 1
|
224
|
+
"#{seconds} seconds"
|
225
|
+
else
|
226
|
+
"1 second"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
144
230
|
def read_response
|
145
231
|
response_length = @connection.gets.to_i
|
146
232
|
if response_length > 0
|
@@ -2,17 +2,17 @@ require 'socket'
|
|
2
2
|
require 'timeout'
|
3
3
|
require 'thread'
|
4
4
|
|
5
|
-
|
5
|
+
module Capybara::Webkit
|
6
6
|
class Connection
|
7
|
+
SERVER_PATH = File.expand_path("../../../../bin/webkit_server", __FILE__)
|
7
8
|
WEBKIT_SERVER_START_TIMEOUT = 15
|
8
9
|
|
9
10
|
attr_reader :port
|
10
11
|
|
11
12
|
def initialize(options = {})
|
12
13
|
@socket_class = options[:socket_class] || TCPSocket
|
13
|
-
@stdout
|
14
|
-
|
15
|
-
$stdout
|
14
|
+
@stdout = options.has_key?(:stdout) ? options[:stdout] : $stdout
|
15
|
+
@command = options[:command] || SERVER_PATH
|
16
16
|
start_server
|
17
17
|
connect
|
18
18
|
end
|
@@ -36,52 +36,50 @@ class Capybara::Driver::Webkit
|
|
36
36
|
private
|
37
37
|
|
38
38
|
def start_server
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
Thread.current.abort_on_exception = true
|
43
|
-
forward_stdout(pipe)
|
44
|
-
end
|
39
|
+
open_pipe
|
40
|
+
discover_port
|
41
|
+
forward_stdout_in_background_thread
|
45
42
|
end
|
46
43
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
44
|
+
def open_pipe
|
45
|
+
@pipe = IO.popen(@command)
|
46
|
+
@pid = @pipe.pid
|
50
47
|
register_shutdown_hook
|
51
|
-
pipe
|
52
|
-
end
|
53
|
-
|
54
|
-
def kill_process(pid)
|
55
|
-
if RUBY_PLATFORM =~ /mingw32/
|
56
|
-
Process.kill(9, pid)
|
57
|
-
else
|
58
|
-
Process.kill("INT", pid)
|
59
|
-
end
|
60
48
|
end
|
61
49
|
|
62
50
|
def register_shutdown_hook
|
63
51
|
@owner_pid = Process.pid
|
64
52
|
at_exit do
|
65
53
|
if Process.pid == @owner_pid
|
66
|
-
kill_process
|
54
|
+
kill_process
|
67
55
|
end
|
68
56
|
end
|
69
57
|
end
|
70
58
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
59
|
+
def kill_process
|
60
|
+
if RUBY_PLATFORM =~ /mingw32/
|
61
|
+
Process.kill(9, @pid)
|
62
|
+
else
|
63
|
+
Process.kill("INT", @pid)
|
64
|
+
end
|
75
65
|
end
|
76
66
|
|
77
|
-
def discover_port
|
78
|
-
|
79
|
-
|
67
|
+
def discover_port
|
68
|
+
if IO.select([@pipe], nil, nil, WEBKIT_SERVER_START_TIMEOUT)
|
69
|
+
@port = ((@pipe.first || '').match(/listening on port: (\d+)/) || [])[1].to_i
|
70
|
+
end
|
80
71
|
end
|
81
72
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
73
|
+
def forward_stdout_in_background_thread
|
74
|
+
@stdout_thread = Thread.new do
|
75
|
+
Thread.current.abort_on_exception = true
|
76
|
+
forward_stdout
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def forward_stdout
|
81
|
+
while pipe_readable?
|
82
|
+
line = @pipe.readline
|
85
83
|
if @stdout
|
86
84
|
@stdout.write(line)
|
87
85
|
@stdout.flush
|
@@ -90,6 +88,20 @@ class Capybara::Driver::Webkit
|
|
90
88
|
rescue EOFError
|
91
89
|
end
|
92
90
|
|
91
|
+
if !defined?(RUBY_ENGINE) || (RUBY_ENGINE == "ruby" && RUBY_VERSION <= "1.8")
|
92
|
+
# please note the use of IO::select() here, as it is used specifically to
|
93
|
+
# preserve correct signal handling behavior in ruby 1.8.
|
94
|
+
# https://github.com/thibaudgg/rb-fsevent/commit/d1a868bf8dc72dbca102bedbadff76c7e6c2dc21
|
95
|
+
# https://github.com/thibaudgg/rb-fsevent/blob/1ca42b987596f350ee7b19d8f8210b7b6ae8766b/ext/fsevent/fsevent_watch.c#L171
|
96
|
+
def pipe_readable?
|
97
|
+
IO.select([@pipe])
|
98
|
+
end
|
99
|
+
else
|
100
|
+
def pipe_readable?
|
101
|
+
!@pipe.eof?
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
93
105
|
def connect
|
94
106
|
Timeout.timeout(5) do
|
95
107
|
while @socket.nil?
|
@@ -100,21 +112,10 @@ class Capybara::Driver::Webkit
|
|
100
112
|
|
101
113
|
def attempt_connect
|
102
114
|
@socket = @socket_class.open("127.0.0.1", @port)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
if !defined?(RUBY_ENGINE) || (RUBY_ENGINE == "ruby" && RUBY_VERSION <= "1.8")
|
107
|
-
# please note the use of IO::select() here, as it is used specifically to
|
108
|
-
# preserve correct signal handling behavior in ruby 1.8.
|
109
|
-
# https://github.com/thibaudgg/rb-fsevent/commit/d1a868bf8dc72dbca102bedbadff76c7e6c2dc21
|
110
|
-
# https://github.com/thibaudgg/rb-fsevent/blob/1ca42b987596f350ee7b19d8f8210b7b6ae8766b/ext/fsevent/fsevent_watch.c#L171
|
111
|
-
def pipe_readable?(pipe)
|
112
|
-
IO.select([pipe])
|
113
|
-
end
|
114
|
-
else
|
115
|
-
def pipe_readable?(pipe)
|
116
|
-
!pipe.eof?
|
115
|
+
if defined?(Socket::TCP_NODELAY)
|
116
|
+
@socket.setsockopt(:IPPROTO_TCP, :TCP_NODELAY, 1)
|
117
117
|
end
|
118
|
+
rescue Errno::ECONNREFUSED
|
118
119
|
end
|
119
120
|
end
|
120
121
|
end
|