capybara-webkit 0.13.2 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.travis.yml +10 -0
  2. data/Gemfile.lock +20 -18
  3. data/NEWS.md +20 -1
  4. data/README.md +12 -10
  5. data/capybara-webkit.gemspec +3 -2
  6. data/lib/capybara/webkit/browser.rb +10 -19
  7. data/lib/capybara/webkit/connection.rb +13 -34
  8. data/lib/capybara/webkit/driver.rb +5 -22
  9. data/lib/capybara/webkit/node.rb +10 -2
  10. data/lib/capybara/webkit/version.rb +1 -1
  11. data/lib/capybara_webkit_builder.rb +10 -1
  12. data/spec/browser_spec.rb +1 -1
  13. data/spec/connection_spec.rb +4 -2
  14. data/spec/driver_rendering_spec.rb +2 -2
  15. data/spec/driver_resize_window_spec.rb +29 -40
  16. data/spec/driver_spec.rb +368 -125
  17. data/spec/integration/session_spec.rb +100 -6
  18. data/spec/spec_helper.rb +6 -9
  19. data/spec/support/app_runner.rb +2 -12
  20. data/src/Authenticate.cpp +2 -2
  21. data/src/ClearCookies.cpp +1 -1
  22. data/src/ClearPromptText.cpp +1 -1
  23. data/src/Command.cpp +13 -0
  24. data/src/Command.h +6 -0
  25. data/src/CommandFactory.cpp +1 -3
  26. data/src/Connection.cpp +4 -3
  27. data/src/ConsoleMessages.cpp +4 -1
  28. data/src/CurrentUrl.cpp +1 -16
  29. data/src/CurrentUrl.h +0 -6
  30. data/src/EnableLogging.cpp +1 -1
  31. data/src/Evaluate.cpp +3 -74
  32. data/src/Evaluate.h +0 -8
  33. data/src/Execute.cpp +2 -2
  34. data/src/Find.cpp +2 -2
  35. data/src/FrameFocus.cpp +3 -3
  36. data/src/GetCookies.cpp +1 -1
  37. data/src/GetTimeout.cpp +1 -1
  38. data/src/GetWindowHandle.cpp +1 -1
  39. data/src/GetWindowHandles.cpp +6 -5
  40. data/src/Header.cpp +2 -2
  41. data/src/Headers.cpp +1 -1
  42. data/src/IgnoreSslErrors.cpp +1 -1
  43. data/src/JavascriptAlertMessages.cpp +4 -1
  44. data/src/JavascriptConfirmMessages.cpp +4 -1
  45. data/src/JavascriptPromptMessages.cpp +4 -1
  46. data/src/JsonSerializer.cpp +116 -0
  47. data/src/JsonSerializer.h +20 -0
  48. data/src/NetworkAccessManager.cpp +58 -17
  49. data/src/NetworkAccessManager.h +6 -0
  50. data/src/NoOpReply.cpp +32 -0
  51. data/src/NoOpReply.h +18 -0
  52. data/src/Node.cpp +1 -1
  53. data/src/NullCommand.cpp +1 -1
  54. data/src/PageLoadingCommand.cpp +5 -4
  55. data/src/Render.cpp +1 -1
  56. data/src/Reset.cpp +1 -1
  57. data/src/ResizeWindow.cpp +1 -1
  58. data/src/Response.cpp +3 -3
  59. data/src/Response.h +13 -4
  60. data/src/SetConfirmAction.cpp +1 -1
  61. data/src/SetCookie.cpp +1 -1
  62. data/src/SetPromptAction.cpp +1 -1
  63. data/src/SetPromptText.cpp +1 -1
  64. data/src/SetProxy.cpp +2 -2
  65. data/src/SetSkipImageLoading.cpp +1 -1
  66. data/src/SetTimeout.cpp +2 -2
  67. data/src/SetUrlBlacklist.cpp +15 -0
  68. data/src/SetUrlBlacklist.h +11 -0
  69. data/src/Status.cpp +1 -1
  70. data/src/TimeoutCommand.cpp +6 -6
  71. data/src/TimeoutCommand.h +0 -3
  72. data/src/UnsupportedContentHandler.cpp +1 -4
  73. data/src/Visit.cpp +1 -1
  74. data/src/WebPage.cpp +41 -31
  75. data/src/WebPage.h +14 -12
  76. data/src/WebPageManager.cpp +13 -8
  77. data/src/WebPageManager.h +3 -2
  78. data/src/WindowFocus.cpp +2 -2
  79. data/src/body.cpp +7 -2
  80. data/src/capybara.js +10 -2
  81. data/src/find_command.h +1 -3
  82. data/src/webkit_server.pro +7 -7
  83. metadata +47 -82
  84. checksums.yaml +0 -7
  85. data/spec/integration/driver_spec.rb +0 -21
  86. data/src/RequestedUrl.cpp +0 -13
  87. data/src/RequestedUrl.h +0 -10
  88. data/src/Source.cpp +0 -19
  89. data/src/Source.h +0 -18
  90. data/src/Url.cpp +0 -13
  91. data/src/Url.h +0 -10
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - rbx-19mode
5
+ matrix:
6
+ allow_failures:
7
+ - rvm: rbx-19mode
8
+ notifications:
9
+ email: false
10
+ script: xvfb-run rake
@@ -1,36 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- capybara-webkit (0.13.2)
5
- capybara (>= 1.0.0, < 1.2)
4
+ capybara-webkit (0.14.0)
5
+ capybara (~> 2.0, >= 2.0.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
14
- capybara (1.1.2)
15
+ capybara (2.0.2)
15
16
  mime-types (>= 1.16)
16
17
  nokogiri (>= 1.3.3)
17
18
  rack (>= 1.0.0)
18
19
  rack-test (>= 0.5.4)
19
20
  selenium-webdriver (~> 2.0)
20
- xpath (~> 0.1.4)
21
- childprocess (0.3.9)
22
- ffi (~> 1.0, >= 1.0.11)
21
+ xpath (~> 1.0.0)
22
+ childprocess (0.3.6)
23
+ ffi (~> 1.0, >= 1.0.6)
23
24
  diff-lcs (1.1.2)
24
- ffi (1.9.0)
25
- json (1.8.0)
26
- mime-types (1.23)
25
+ ffi (1.2.0)
26
+ json (1.7.6)
27
+ libwebsocket (0.1.7.1)
28
+ addressable
29
+ websocket
30
+ mime-types (1.19)
27
31
  mini_magick (3.2.1)
28
32
  subexec (~> 0.0.4)
29
- mini_portile (0.5.1)
30
- multi_json (1.7.8)
31
- nokogiri (1.6.0)
32
- mini_portile (~> 0.5.0)
33
- rack (1.3.2)
33
+ multi_json (1.5.0)
34
+ nokogiri (1.5.6)
35
+ rack (1.4.1)
34
36
  rack-test (0.6.2)
35
37
  rack (>= 1.0)
36
38
  rake (0.9.2)
@@ -43,18 +45,18 @@ GEM
43
45
  diff-lcs (~> 1.1.2)
44
46
  rspec-mocks (2.6.0)
45
47
  rubyzip (0.9.9)
46
- selenium-webdriver (2.33.0)
48
+ selenium-webdriver (2.27.2)
47
49
  childprocess (>= 0.2.5)
50
+ libwebsocket (~> 0.1.3)
48
51
  multi_json (~> 1.0)
49
52
  rubyzip
50
- websocket (~> 1.0.4)
51
53
  sinatra (1.1.2)
52
54
  rack (~> 1.1)
53
55
  tilt (~> 1.2)
54
56
  subexec (0.0.4)
55
57
  tilt (1.2.2)
56
- websocket (1.0.7)
57
- xpath (0.1.4)
58
+ websocket (1.0.6)
59
+ xpath (1.0.0)
58
60
  nokogiri (~> 1.3)
59
61
 
60
62
  PLATFORMS
data/NEWS.md CHANGED
@@ -1,4 +1,23 @@
1
- New for HEAD:
1
+ New for 0.14.0:
2
+
3
+ * URL blacklist support.
4
+ * Various fixes for JavaScript console messages.
5
+ * Various compilation fixes.
6
+ * Fix status code and headers commands for iframes.
7
+ * Capybara 2.0 compatibility.
8
+ * Driver#render replaced by Session#save_screenshot.
9
+ * Driver#source and Driver#body return the HTML representation of the DOM. Unsupported content is returned as plain text.
10
+ * HTML5 multi-file upload support.
11
+ * Driver#url and Driver#requested_url removed.
12
+ * JavaScipt console messages and alerts are now written to the logger instead of directly to stdout.
13
+ * Dropped support for Qt 4.7.
14
+ * Fix deadlocks encountered during page load.
15
+ * Delete Response objects when commands have timed out.
16
+ * Fix an infinite loop when invalid credentials are used for HTTP auth.
17
+ * Ensure queued commands start only after pending commands have finished.
18
+ * Fix segfaults related to web fonts on OS X.
19
+
20
+ New for 0.13.0:
2
21
 
3
22
  * Better detect page load success, and better handle load failures.
4
23
  * HTTP Basic Auth support.
data/README.md CHANGED
@@ -1,22 +1,24 @@
1
1
  capybara-webkit
2
2
  ===============
3
3
 
4
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thoughtbot/capybara-webkit)
4
+ [![Build Status](https://secure.travis-ci.org/thoughtbot/capybara-webkit.png?branch=master)](https://travis-ci.org/thoughtbot/capybara-webkit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/thoughtbot/capybara-webkit)
5
5
 
6
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).
7
7
 
8
8
  Qt Dependency and Installation Issues
9
- -------------
9
+ -------------------------------------
10
10
 
11
11
  capybara-webkit depends on a WebKit implementation from Qt, a cross-platform
12
12
  development toolkit. You'll need to download the Qt libraries to build and
13
13
  install the gem. You can find instructions for downloading and installing QT on
14
- the [capybara-webkit wiki](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit)
14
+ the
15
+ [capybara-webkit wiki](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit).
16
+ capybara-webkit requires Qt version 4.8.
15
17
 
16
18
  Windows Support
17
19
  ---------------
18
20
 
19
- Currently 32bit Windows will compile Capybara-webkit. Support for Windows is provided by the open source community and Windows related issues should be posted to the [mailing list](http://groups.google.com/group/capybara-webkit)
21
+ Currently 32-bit Windows will compile capybara-webkit. Support for Windows is provided by the open source community and Windows related issues should be posted to the [mailing list](http://groups.google.com/group/capybara-webkit)
20
22
 
21
23
  Reporting Issues
22
24
  ----------------
@@ -53,7 +55,7 @@ Set your Capybara Javascript driver to webkit:
53
55
 
54
56
  In cucumber, tag scenarios with @javascript to run them using a headless WebKit browser.
55
57
 
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.
58
+ 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.
57
59
 
58
60
  Take note of the transactional fixtures section of the [capybara README](https://github.com/jnicklas/capybara/blob/master/README.md).
59
61
 
@@ -99,10 +101,6 @@ capybara-webkit supports a few methods that are not part of the standard capybar
99
101
  page.driver.evaluate_script("window.innerWidth")
100
102
  => 500
101
103
 
102
- **render**: render a screenshot of the current view (requires [mini_magick](https://github.com/probablycorey/mini_magick) and [ImageMagick](http://www.imagemagick.org))
103
-
104
- page.driver.render "tmp/screenshot.png"
105
-
106
104
  **cookies**: allows read-only access of cookies for the current session
107
105
 
108
106
  page.driver.cookies["alpha"]
@@ -171,6 +169,10 @@ capybara-webkit supports a few methods that are not part of the standard capybar
171
169
  page.driver.console_messages.first[:message]
172
170
  => "42"
173
171
 
172
+ **header**: set the given HTTP header for subsequent requests
173
+
174
+ page.driver.header 'Referer', 'https://www.thoughtbot.com'
175
+
174
176
  Contributing
175
177
  ------------
176
178
 
@@ -179,7 +181,7 @@ See the CONTRIBUTING document.
179
181
  About
180
182
  -----
181
183
 
182
- The capybara WebKit driver is maintained by Joe Ferris and Matt Mongeau. It was written by [thoughtbot, inc](http://thoughtbot.com/community) with the help of numerous [contributions from the open source community](https://github.com/thoughtbot/capybara-webkit/contributors).
184
+ The capybara WebKit driver is maintained by Joe Ferris and Matt Horan. It was written by [thoughtbot, inc](http://thoughtbot.com/community) with the help of numerous [contributions from the open source community](https://github.com/thoughtbot/capybara-webkit/contributors).
183
185
 
184
186
  Code for rendering the current webpage to a PNG is borrowed from Phantom.js' implementation.
185
187
 
@@ -4,7 +4,8 @@ require "capybara/webkit/version"
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "capybara-webkit"
6
6
  s.version = Capybara::Driver::Webkit::VERSION.dup
7
- s.authors = ["thoughtbot", "Joe Ferris", "Matt Mongeau", "Mike Burns", "Jason Morrison"]
7
+ s.authors = ["thoughtbot", "Joe Ferris", "Matt Horan", "Matt Mongeau",
8
+ "Mike Burns", "Jason Morrison"]
8
9
  s.email = "support@thoughtbot.com"
9
10
  s.homepage = "http://github.com/thoughtbot/capybara-webkit"
10
11
  s.summary = "Headless Webkit driver for Capybara"
@@ -15,7 +16,7 @@ Gem::Specification.new do |s|
15
16
 
16
17
  s.extensions = "extconf.rb"
17
18
 
18
- s.add_runtime_dependency("capybara", [">= 1.0.0", "< 1.2"])
19
+ s.add_runtime_dependency("capybara", "~> 2.0", ">= 2.0.2")
19
20
  s.add_runtime_dependency("json")
20
21
 
21
22
  s.add_development_dependency("rspec", "~> 2.6.0")
@@ -34,18 +34,13 @@ module Capybara::Webkit
34
34
  command("Body")
35
35
  end
36
36
 
37
- def source
38
- command("Source")
39
- end
40
-
41
37
  def status_code
42
38
  command("Status").to_i
43
39
  end
44
40
 
45
41
  def console_messages
46
- command("ConsoleMessages").split("\n").map do |messages|
47
- parts = messages.split("|", 3)
48
- { :source => parts.first, :line_number => Integer(parts[1]), :message => parts.last }
42
+ JSON.parse(command("ConsoleMessages")).map do |message|
43
+ message.inject({}) { |m,(k,v)| m.merge(k.to_sym => v) }
49
44
  end
50
45
  end
51
46
 
@@ -56,29 +51,21 @@ module Capybara::Webkit
56
51
  end
57
52
 
58
53
  def alert_messages
59
- command("JavascriptAlertMessages").split("\n")
54
+ JSON.parse(command("JavascriptAlertMessages"))
60
55
  end
61
56
 
62
57
  def confirm_messages
63
- command("JavascriptConfirmMessages").split("\n")
58
+ JSON.parse(command("JavascriptConfirmMessages"))
64
59
  end
65
60
 
66
61
  def prompt_messages
67
- command("JavascriptPromptMessages").split("\n")
62
+ JSON.parse(command("JavascriptPromptMessages"))
68
63
  end
69
64
 
70
65
  def response_headers
71
66
  Hash[command("Headers").split("\n").map { |header| header.split(": ") }]
72
67
  end
73
68
 
74
- def url
75
- command("Url")
76
- end
77
-
78
- def requested_url
79
- command("RequestedUrl")
80
- end
81
-
82
69
  def current_url
83
70
  command("CurrentUrl")
84
71
  end
@@ -141,6 +128,10 @@ module Capybara::Webkit
141
128
  command("ClearPromptText")
142
129
  end
143
130
 
131
+ def url_blacklist=(black_list)
132
+ command("SetUrlBlacklist", *Array(black_list))
133
+ end
134
+
144
135
  def command(name, *args)
145
136
  @connection.puts name
146
137
  @connection.puts args.size
@@ -209,7 +200,7 @@ module Capybara::Webkit
209
200
  elsif result != 'ok'
210
201
  case response = read_response
211
202
  when "timeout"
212
- raise Capybara::TimeoutError, "Request timed out after #{timeout_seconds}"
203
+ raise Timeout::Error, "Request timed out after #{timeout_seconds}"
213
204
  else
214
205
  raise InvalidResponseError, response
215
206
  end
@@ -1,6 +1,7 @@
1
1
  require 'socket'
2
2
  require 'timeout'
3
3
  require 'thread'
4
+ require 'open3'
4
5
 
5
6
  module Capybara::Webkit
6
7
  class Connection
@@ -11,8 +12,7 @@ module Capybara::Webkit
11
12
 
12
13
  def initialize(options = {})
13
14
  @socket_class = options[:socket_class] || TCPSocket
14
- @stdout = options.has_key?(:stdout) ? options[:stdout] : $stdout
15
- @command = options[:command] || SERVER_PATH
15
+ @output_target = options.has_key?(:stdout) ? options[:stdout] : $stdout
16
16
  start_server
17
17
  connect
18
18
  end
@@ -38,12 +38,12 @@ module Capybara::Webkit
38
38
  def start_server
39
39
  open_pipe
40
40
  discover_port
41
- forward_stdout_in_background_thread
41
+ forward_output_in_background_thread
42
42
  end
43
43
 
44
44
  def open_pipe
45
- @pipe = IO.popen(@command)
46
- @pid = @pipe.pid
45
+ _, @pipe_stdout, @pipe_stderr, wait_thr = Open3.popen3(SERVER_PATH)
46
+ @pid = wait_thr[:pid]
47
47
  register_shutdown_hook
48
48
  end
49
49
 
@@ -65,40 +65,19 @@ module Capybara::Webkit
65
65
  end
66
66
 
67
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
68
+ if IO.select([@pipe_stdout], nil, nil, WEBKIT_SERVER_START_TIMEOUT)
69
+ @port = ((@pipe_stdout.first || '').match(/listening on port: (\d+)/) || [])[1].to_i
70
70
  end
71
71
  end
72
72
 
73
- def forward_stdout_in_background_thread
74
- @stdout_thread = Thread.new do
73
+ def forward_output_in_background_thread
74
+ Thread.new do
75
75
  Thread.current.abort_on_exception = true
76
- forward_stdout
76
+ IO.copy_stream(@pipe_stdout, @output_target)
77
77
  end
78
- end
79
-
80
- def forward_stdout
81
- while pipe_readable?
82
- line = @pipe.readline
83
- if @stdout
84
- @stdout.write(line)
85
- @stdout.flush
86
- end
87
- end
88
- rescue EOFError
89
- end
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?
78
+ Thread.new do
79
+ Thread.current.abort_on_exception = true
80
+ IO.copy_stream(@pipe_stderr, @output_target)
102
81
  end
103
82
  end
104
83
 
@@ -14,8 +14,6 @@ module Capybara::Webkit
14
14
  def initialize(app, options={})
15
15
  @app = app
16
16
  @options = options
17
- @rack_server = Capybara::Server.new(@app)
18
- @rack_server.boot if Capybara.run_server
19
17
  @browser = options[:browser] || Browser.new(Connection.new(options))
20
18
  end
21
19
 
@@ -27,23 +25,15 @@ module Capybara::Webkit
27
25
  browser.current_url
28
26
  end
29
27
 
30
- def requested_url
31
- browser.requested_url
32
- end
33
-
34
28
  def visit(path)
35
- browser.visit(url(path))
29
+ browser.visit(path)
36
30
  end
37
31
 
38
32
  def find(query)
39
33
  browser.find(query).map { |native| Node.new(self, native) }
40
34
  end
41
35
 
42
- def source
43
- browser.source
44
- end
45
-
46
- def body
36
+ def html
47
37
  browser.body
48
38
  end
49
39
 
@@ -147,7 +137,8 @@ module Capybara::Webkit
147
137
  true
148
138
  end
149
139
 
150
- def wait_until(*args)
140
+ def needs_server?
141
+ true
151
142
  end
152
143
 
153
144
  def reset!
@@ -158,17 +149,13 @@ module Capybara::Webkit
158
149
  false
159
150
  end
160
151
 
161
- def render(path, options={})
152
+ def save_screenshot(path, options={})
162
153
  options[:width] ||= 1000
163
154
  options[:height] ||= 10
164
155
 
165
156
  browser.render path, options[:width], options[:height]
166
157
  end
167
158
 
168
- def server_port
169
- @rack_server.port
170
- end
171
-
172
159
  def cookies
173
160
  @cookie_jar ||= CookieJar.new(browser)
174
161
  end
@@ -178,9 +165,5 @@ module Capybara::Webkit
178
165
  end
179
166
 
180
167
  private
181
-
182
- def url(path)
183
- @rack_server.url(path)
184
- end
185
168
  end
186
169
  end
@@ -12,7 +12,11 @@ module Capybara::Webkit
12
12
  if name == 'checked' || name == 'disabled' || name == 'multiple'
13
13
  value == 'true'
14
14
  else
15
- value
15
+ if invoke("hasAttribute", name) == 'true'
16
+ value
17
+ else
18
+ nil
19
+ end
16
20
  end
17
21
  end
18
22
 
@@ -33,7 +37,7 @@ module Capybara::Webkit
33
37
  end
34
38
 
35
39
  def set(value)
36
- invoke "set", value
40
+ invoke "set", *[value].flatten
37
41
  end
38
42
 
39
43
  def select_option
@@ -122,5 +126,9 @@ module Capybara::Webkit
122
126
  def multiple_select?
123
127
  self.tag_name == "select" && self["multiple"]
124
128
  end
129
+
130
+ def ==(other)
131
+ invoke("equals", other.native) == "true"
132
+ end
125
133
  end
126
134
  end