capybara-webkit 0.14.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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