capybara-webkit 0.14.2 → 1.0.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.
Files changed (111) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +21 -0
  3. data/Appraisals +4 -4
  4. data/CONTRIBUTING.md +14 -3
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +27 -19
  7. data/NEWS.md +15 -0
  8. data/README.md +126 -76
  9. data/Vagrantfile +7 -0
  10. data/capybara-webkit.gemspec +3 -0
  11. data/gemfiles/2.0.gemfile +7 -0
  12. data/gemfiles/2.0.gemfile.lock +72 -0
  13. data/gemfiles/2.1.gemfile +7 -0
  14. data/gemfiles/2.1.gemfile.lock +71 -0
  15. data/lib/capybara/webkit/browser.rb +22 -22
  16. data/lib/capybara/webkit/connection.rb +9 -6
  17. data/lib/capybara/webkit/driver.rb +22 -6
  18. data/lib/capybara/webkit/errors.rb +25 -0
  19. data/lib/capybara/webkit/node.rb +36 -10
  20. data/lib/capybara/webkit/version.rb +1 -1
  21. data/spec/browser_spec.rb +16 -1
  22. data/spec/capybara_webkit_builder_spec.rb +9 -3
  23. data/spec/connection_spec.rb +19 -3
  24. data/spec/driver_spec.rb +324 -144
  25. data/spec/errors_spec.rb +11 -0
  26. data/spec/integration/session_spec.rb +244 -0
  27. data/spec/selenium_compatibility_spec.rb +3 -1
  28. data/spec/spec_helper.rb +1 -9
  29. data/src/Authenticate.cpp +3 -2
  30. data/src/ClearCookies.cpp +1 -1
  31. data/src/ClearPromptText.cpp +1 -1
  32. data/src/Command.cpp +8 -4
  33. data/src/Command.h +7 -4
  34. data/src/CommandFactory.cpp +4 -2
  35. data/src/CommandParser.cpp +1 -1
  36. data/src/Connection.cpp +4 -4
  37. data/src/ConsoleMessages.cpp +1 -1
  38. data/src/CurrentUrl.cpp +2 -2
  39. data/src/EnableLogging.cpp +1 -1
  40. data/src/ErrorMessage.cpp +26 -0
  41. data/src/ErrorMessage.h +21 -0
  42. data/src/Evaluate.cpp +1 -1
  43. data/src/Execute.cpp +3 -2
  44. data/src/FindCss.cpp +13 -0
  45. data/src/FindCss.h +11 -0
  46. data/src/FindXpath.cpp +13 -0
  47. data/src/FindXpath.h +11 -0
  48. data/src/FrameFocus.cpp +4 -3
  49. data/src/GetCookies.cpp +1 -1
  50. data/src/GetTimeout.cpp +1 -1
  51. data/src/GetWindowHandle.cpp +1 -1
  52. data/src/GetWindowHandles.cpp +1 -1
  53. data/src/Header.cpp +2 -2
  54. data/src/Headers.cpp +1 -6
  55. data/src/IgnoreSslErrors.cpp +1 -1
  56. data/src/InvocationResult.cpp +29 -0
  57. data/src/InvocationResult.h +16 -0
  58. data/src/JavascriptAlertMessages.cpp +1 -1
  59. data/src/JavascriptCommand.cpp +15 -0
  60. data/src/JavascriptCommand.h +20 -0
  61. data/src/JavascriptConfirmMessages.cpp +1 -1
  62. data/src/JavascriptInvocation.cpp +128 -1
  63. data/src/JavascriptInvocation.h +22 -1
  64. data/src/JavascriptPromptMessages.cpp +1 -1
  65. data/src/NetworkAccessManager.cpp +8 -16
  66. data/src/NetworkAccessManager.h +5 -11
  67. data/src/NetworkReplyProxy.cpp +91 -0
  68. data/src/NetworkReplyProxy.h +65 -0
  69. data/src/Node.cpp +4 -4
  70. data/src/Node.h +2 -2
  71. data/src/NullCommand.cpp +2 -1
  72. data/src/PageLoadingCommand.cpp +2 -1
  73. data/src/Render.cpp +1 -1
  74. data/src/Reset.cpp +1 -1
  75. data/src/ResizeWindow.cpp +1 -1
  76. data/src/Response.cpp +7 -0
  77. data/src/Response.h +8 -3
  78. data/src/SetConfirmAction.cpp +1 -1
  79. data/src/SetCookie.cpp +2 -2
  80. data/src/SetPromptAction.cpp +1 -1
  81. data/src/SetPromptText.cpp +1 -1
  82. data/src/SetProxy.cpp +2 -2
  83. data/src/SetSkipImageLoading.cpp +1 -1
  84. data/src/SetTimeout.cpp +3 -2
  85. data/src/SetUrlBlacklist.cpp +2 -2
  86. data/src/Status.cpp +1 -1
  87. data/src/TimeoutCommand.cpp +4 -2
  88. data/src/Title.cpp +11 -0
  89. data/src/Title.h +9 -0
  90. data/src/Version.cpp +13 -0
  91. data/src/Version.h +10 -0
  92. data/src/Visit.cpp +1 -1
  93. data/src/WebPage.cpp +49 -27
  94. data/src/WebPage.h +14 -7
  95. data/src/WebPageManager.cpp +10 -1
  96. data/src/WebPageManager.h +4 -1
  97. data/src/WindowFocus.cpp +3 -2
  98. data/src/body.cpp +3 -6
  99. data/src/capybara.js +103 -101
  100. data/src/find_command.h +4 -2
  101. data/src/main.cpp +1 -1
  102. data/src/stable.h +39 -0
  103. data/src/webkit_server.pro +26 -6
  104. data/vagrant_setup.sh +58 -0
  105. metadata +51 -78
  106. data/gemfiles/1.0.gemfile +0 -7
  107. data/gemfiles/1.0.gemfile.lock +0 -70
  108. data/gemfiles/1.1.gemfile +0 -7
  109. data/gemfiles/1.1.gemfile.lock +0 -70
  110. data/src/Find.cpp +0 -20
  111. data/src/Find.h +0 -11
data/Vagrantfile ADDED
@@ -0,0 +1,7 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant::Config.run do |config|
5
+ config.vm.box = "precise32"
6
+ config.vm.provision :shell, :path => 'vagrant_setup.sh'
7
+ end
@@ -16,6 +16,8 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.extensions = "extconf.rb"
18
18
 
19
+ s.required_ruby_version = ">= 1.9.0"
20
+
19
21
  s.add_runtime_dependency("capybara", "~> 2.0", ">= 2.0.2")
20
22
  s.add_runtime_dependency("json")
21
23
 
@@ -25,5 +27,6 @@ Gem::Specification.new do |s|
25
27
  s.add_development_dependency("mini_magick")
26
28
  s.add_development_dependency("rake")
27
29
  s.add_development_dependency("appraisal", "~> 0.4.0")
30
+ s.add_development_dependency("selenium-webdriver")
28
31
  end
29
32
 
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "capybara", "~> 2.0.2"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: /home/mhoran/capybara-webkit
3
+ specs:
4
+ capybara-webkit (1.0.0)
5
+ capybara (~> 2.0, >= 2.0.2)
6
+ json
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ appraisal (0.4.1)
12
+ bundler
13
+ rake
14
+ capybara (2.0.2)
15
+ mime-types (>= 1.16)
16
+ nokogiri (>= 1.3.3)
17
+ rack (>= 1.0.0)
18
+ rack-test (>= 0.5.4)
19
+ selenium-webdriver (~> 2.0)
20
+ xpath (~> 1.0.0)
21
+ childprocess (0.3.8)
22
+ ffi (~> 1.0, >= 1.0.11)
23
+ diff-lcs (1.1.3)
24
+ ffi (1.4.0)
25
+ json (1.8.0)
26
+ mime-types (1.21)
27
+ mini_magick (3.5.0)
28
+ subexec (~> 0.2.1)
29
+ multi_json (1.6.1)
30
+ nokogiri (1.5.6)
31
+ rack (1.5.2)
32
+ rack-protection (1.3.2)
33
+ rack
34
+ rack-test (0.6.2)
35
+ rack (>= 1.0)
36
+ rake (10.0.3)
37
+ rspec (2.6.0)
38
+ rspec-core (~> 2.6.0)
39
+ rspec-expectations (~> 2.6.0)
40
+ rspec-mocks (~> 2.6.0)
41
+ rspec-core (2.6.4)
42
+ rspec-expectations (2.6.0)
43
+ diff-lcs (~> 1.1.2)
44
+ rspec-mocks (2.6.0)
45
+ rubyzip (0.9.9)
46
+ selenium-webdriver (2.30.0)
47
+ childprocess (>= 0.2.5)
48
+ multi_json (~> 1.0)
49
+ rubyzip
50
+ websocket (~> 1.0.4)
51
+ sinatra (1.3.5)
52
+ rack (~> 1.4)
53
+ rack-protection (~> 1.3)
54
+ tilt (~> 1.3, >= 1.3.3)
55
+ subexec (0.2.2)
56
+ tilt (1.3.3)
57
+ websocket (1.0.7)
58
+ xpath (1.0.0)
59
+ nokogiri (~> 1.3)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ appraisal (~> 0.4.0)
66
+ capybara (~> 2.0.2)
67
+ capybara-webkit!
68
+ mini_magick
69
+ rake
70
+ rspec (~> 2.6.0)
71
+ selenium-webdriver
72
+ sinatra
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "capybara", "~> 2.1.0"
6
+
7
+ gemspec :path=>"../"
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: /home/mhoran/capybara-webkit
3
+ specs:
4
+ capybara-webkit (1.0.0)
5
+ capybara (~> 2.0, >= 2.0.2)
6
+ json
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ appraisal (0.4.1)
12
+ bundler
13
+ rake
14
+ capybara (2.1.0)
15
+ mime-types (>= 1.16)
16
+ nokogiri (>= 1.3.3)
17
+ rack (>= 1.0.0)
18
+ rack-test (>= 0.5.4)
19
+ xpath (~> 2.0)
20
+ childprocess (0.3.8)
21
+ ffi (~> 1.0, >= 1.0.11)
22
+ diff-lcs (1.1.3)
23
+ ffi (1.4.0)
24
+ json (1.8.0)
25
+ mime-types (1.22)
26
+ mini_magick (3.5.0)
27
+ subexec (~> 0.2.1)
28
+ multi_json (1.6.1)
29
+ nokogiri (1.5.9)
30
+ rack (1.5.2)
31
+ rack-protection (1.3.2)
32
+ rack
33
+ rack-test (0.6.2)
34
+ rack (>= 1.0)
35
+ rake (10.0.3)
36
+ rspec (2.6.0)
37
+ rspec-core (~> 2.6.0)
38
+ rspec-expectations (~> 2.6.0)
39
+ rspec-mocks (~> 2.6.0)
40
+ rspec-core (2.6.4)
41
+ rspec-expectations (2.6.0)
42
+ diff-lcs (~> 1.1.2)
43
+ rspec-mocks (2.6.0)
44
+ rubyzip (0.9.9)
45
+ selenium-webdriver (2.30.0)
46
+ childprocess (>= 0.2.5)
47
+ multi_json (~> 1.0)
48
+ rubyzip
49
+ websocket (~> 1.0.4)
50
+ sinatra (1.3.5)
51
+ rack (~> 1.4)
52
+ rack-protection (~> 1.3)
53
+ tilt (~> 1.3, >= 1.3.3)
54
+ subexec (0.2.2)
55
+ tilt (1.3.3)
56
+ websocket (1.0.7)
57
+ xpath (2.0.0)
58
+ nokogiri (~> 1.3)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ appraisal (~> 0.4.0)
65
+ capybara (~> 2.1.0)
66
+ capybara-webkit!
67
+ mini_magick
68
+ rake
69
+ rspec (~> 2.6.0)
70
+ selenium-webdriver
71
+ sinatra
@@ -22,8 +22,16 @@ module Capybara::Webkit
22
22
  command("Header", key, value)
23
23
  end
24
24
 
25
- def find(query)
26
- command("Find", query).split(",")
25
+ def title
26
+ command("Title")
27
+ end
28
+
29
+ def find_xpath(query)
30
+ command("FindXpath", query).split(",")
31
+ end
32
+
33
+ def find_css(query)
34
+ command("FindCss", query).split(",")
27
35
  end
28
36
 
29
37
  def reset!
@@ -70,11 +78,13 @@ module Capybara::Webkit
70
78
  command("CurrentUrl")
71
79
  end
72
80
 
73
- def frame_focus(frame_id_or_index=nil)
74
- if frame_id_or_index.is_a? Fixnum
75
- command("FrameFocus", "", frame_id_or_index.to_s)
76
- elsif frame_id_or_index
77
- command("FrameFocus", frame_id_or_index)
81
+ def frame_focus(selector=nil)
82
+ if selector.respond_to?(:base)
83
+ selector.base.invoke('focus')
84
+ elsif selector.is_a? Fixnum
85
+ command("FrameFocus", "", selector.to_s)
86
+ elsif selector
87
+ command("FrameFocus", selector)
78
88
  else
79
89
  command("FrameFocus")
80
90
  end
@@ -189,6 +199,10 @@ module Capybara::Webkit
189
199
  command("ResizeWindow", width.to_i, height.to_i)
190
200
  end
191
201
 
202
+ def version
203
+ command("Version")
204
+ end
205
+
192
206
  private
193
207
 
194
208
  def check
@@ -198,26 +212,12 @@ module Capybara::Webkit
198
212
  if result.nil?
199
213
  raise NoResponseError, "No response received from the server."
200
214
  elsif result != 'ok'
201
- case response = read_response
202
- when "timeout"
203
- raise Timeout::Error, "Request timed out after #{timeout_seconds}"
204
- else
205
- raise InvalidResponseError, response
206
- end
215
+ raise JsonError.new(read_response)
207
216
  end
208
217
 
209
218
  result
210
219
  end
211
220
 
212
- def timeout_seconds
213
- seconds = timeout
214
- if seconds > 1
215
- "#{seconds} seconds"
216
- else
217
- "1 second"
218
- end
219
- end
220
-
221
221
  def read_response
222
222
  response_length = @connection.gets.to_i
223
223
  if response_length > 0
@@ -12,7 +12,14 @@ module Capybara::Webkit
12
12
 
13
13
  def initialize(options = {})
14
14
  @socket_class = options[:socket_class] || TCPSocket
15
- @output_target = options.has_key?(:stdout) ? options[:stdout] : $stdout
15
+ if options.has_key?(:stderr)
16
+ @output_target = options[:stderr]
17
+ elsif options.has_key?(:stdout)
18
+ warn "[DEPRECATION] The `stdout` option is deprecated. Please use `stderr` instead."
19
+ @output_target = options[:stdout]
20
+ else
21
+ @output_target = $stderr
22
+ end
16
23
  start_server
17
24
  connect
18
25
  end
@@ -75,11 +82,7 @@ module Capybara::Webkit
75
82
  def forward_output_in_background_thread
76
83
  Thread.new do
77
84
  Thread.current.abort_on_exception = true
78
- IO.copy_stream(@pipe_stdout, @output_target)
79
- end
80
- Thread.new do
81
- Thread.current.abort_on_exception = true
82
- IO.copy_stream(@pipe_stderr, @output_target)
85
+ IO.copy_stream(@pipe_stderr, @output_target) if @output_target
83
86
  end
84
87
  end
85
88
 
@@ -29,8 +29,14 @@ module Capybara::Webkit
29
29
  browser.visit(path)
30
30
  end
31
31
 
32
- def find(query)
33
- browser.find(query).map { |native| Node.new(self, native) }
32
+ def find_xpath(xpath)
33
+ browser.find_xpath(xpath).map { |native| Node.new(self, native) }
34
+ end
35
+
36
+ alias_method :find, :find_xpath
37
+
38
+ def find_css(selector)
39
+ browser.find_css(selector).map { |native| Node.new(self, native) }
34
40
  end
35
41
 
36
42
  def html
@@ -41,6 +47,10 @@ module Capybara::Webkit
41
47
  browser.header(key, value)
42
48
  end
43
49
 
50
+ def title
51
+ browser.title
52
+ end
53
+
44
54
  def execute_script(script)
45
55
  value = browser.execute_script script
46
56
  value.empty? ? nil : value
@@ -82,8 +92,8 @@ module Capybara::Webkit
82
92
  browser.resize_window(width, height)
83
93
  end
84
94
 
85
- def within_frame(frame_id_or_index)
86
- browser.frame_focus(frame_id_or_index)
95
+ def within_frame(selector)
96
+ browser.frame_focus(selector)
87
97
  begin
88
98
  yield
89
99
  ensure
@@ -161,9 +171,15 @@ module Capybara::Webkit
161
171
  end
162
172
 
163
173
  def invalid_element_errors
164
- []
174
+ [Capybara::Webkit::ClickFailed]
165
175
  end
166
176
 
167
- private
177
+ def version
178
+ [
179
+ "Capybara: #{Capybara::VERSION}",
180
+ "capybara-webkit: #{Capybara::Driver::Webkit::VERSION}",
181
+ browser.version
182
+ ].join("\n")
183
+ end
168
184
  end
169
185
  end
@@ -7,4 +7,29 @@ module Capybara::Webkit
7
7
 
8
8
  class NodeNotAttachedError < Capybara::ElementNotFound
9
9
  end
10
+
11
+ class ClickFailed < StandardError
12
+ end
13
+
14
+ class TimeoutError < Timeout::Error
15
+ end
16
+
17
+ class JsonError
18
+ def initialize(response)
19
+ error = JSON.parse response
20
+
21
+ @class_name = error['class']
22
+ @message = error['message']
23
+ end
24
+
25
+ def exception
26
+ error_class.new @message
27
+ end
28
+
29
+ private
30
+
31
+ def error_class
32
+ Capybara::Webkit.const_get @class_name
33
+ end
34
+ end
10
35
  end
@@ -1,10 +1,12 @@
1
1
  module Capybara::Webkit
2
2
  class Node < Capybara::Driver::Node
3
- NBSP = "\xC2\xA0"
4
- NBSP.force_encoding("UTF-8") if NBSP.respond_to?(:force_encoding)
3
+ def visible_text
4
+ Capybara::Helpers.normalize_whitespace(invoke("text"))
5
+ end
6
+ alias_method :text, :visible_text
5
7
 
6
- def text
7
- invoke("text").gsub(NBSP, ' ').gsub(/\s+/u, ' ').strip
8
+ def all_text
9
+ Capybara::Helpers.normalize_whitespace(invoke("allText"))
8
10
  end
9
11
 
10
12
  def [](name)
@@ -22,7 +24,7 @@ module Capybara::Webkit
22
24
 
23
25
  def value
24
26
  if multiple_select?
25
- self.find(".//option").select(&:selected?).map(&:value)
27
+ self.find_xpath(".//option").select(&:selected?).map(&:value)
26
28
  else
27
29
  invoke "value"
28
30
  end
@@ -45,7 +47,7 @@ module Capybara::Webkit
45
47
  end
46
48
 
47
49
  def unselect_option
48
- select = find("ancestor::select").first
50
+ select = find_xpath("ancestor::select").first
49
51
  if select.multiple_select?
50
52
  invoke "unselectOption"
51
53
  else
@@ -54,7 +56,19 @@ module Capybara::Webkit
54
56
  end
55
57
 
56
58
  def click
57
- invoke "click"
59
+ invoke("leftClick")
60
+ end
61
+
62
+ def double_click
63
+ invoke("doubleClick")
64
+ end
65
+
66
+ def right_click
67
+ invoke("rightClick")
68
+ end
69
+
70
+ def hover
71
+ invoke("hover")
58
72
  end
59
73
 
60
74
  def drag_to(element)
@@ -78,7 +92,11 @@ module Capybara::Webkit
78
92
  end
79
93
 
80
94
  def disabled?
81
- self['disabled']
95
+ if %w(option optgroup).include? tag_name
96
+ self['disabled'] || find_xpath("parent::*")[0].disabled?
97
+ else
98
+ self['disabled']
99
+ end
82
100
  end
83
101
 
84
102
  def path
@@ -93,8 +111,16 @@ module Capybara::Webkit
93
111
  invoke "trigger", event
94
112
  end
95
113
 
96
- def find(xpath)
97
- invoke("findWithin", xpath).split(',').map do |native|
114
+ def find_xpath(xpath)
115
+ invoke("findXpathWithin", xpath).split(',').map do |native|
116
+ self.class.new(driver, native)
117
+ end
118
+ end
119
+
120
+ alias_method :find, :find_xpath
121
+
122
+ def find_css(selector)
123
+ invoke("findCssWithin", selector).split(',').map do |native|
98
124
  self.class.new(driver, native)
99
125
  end
100
126
  end