celerity 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/History.txt +36 -0
  2. data/Manifest.txt +82 -0
  3. data/README.rdoc +78 -0
  4. data/Rakefile +25 -10
  5. data/celerity.gemspec +40 -0
  6. data/lib/celerity.rb +36 -20
  7. data/lib/celerity/browser.rb +396 -189
  8. data/lib/celerity/clickable_element.rb +25 -5
  9. data/lib/celerity/collections.rb +2 -2
  10. data/lib/celerity/container.rb +74 -61
  11. data/lib/celerity/default_viewer.rb +8 -4
  12. data/lib/celerity/disabled_element.rb +5 -5
  13. data/lib/celerity/element.rb +57 -35
  14. data/lib/celerity/element_collection.rb +22 -21
  15. data/lib/celerity/element_locator.rb +25 -18
  16. data/lib/celerity/elements/button.rb +13 -11
  17. data/lib/celerity/elements/file_field.rb +8 -4
  18. data/lib/celerity/elements/form.rb +7 -5
  19. data/lib/celerity/elements/frame.rb +6 -4
  20. data/lib/celerity/elements/image.rb +4 -4
  21. data/lib/celerity/elements/label.rb +1 -1
  22. data/lib/celerity/elements/link.rb +5 -5
  23. data/lib/celerity/elements/meta.rb +2 -1
  24. data/lib/celerity/elements/non_control_elements.rb +3 -3
  25. data/lib/celerity/elements/option.rb +7 -7
  26. data/lib/celerity/elements/radio_check.rb +18 -18
  27. data/lib/celerity/elements/select_list.rb +55 -25
  28. data/lib/celerity/elements/table.rb +21 -18
  29. data/lib/celerity/elements/table_cell.rb +1 -1
  30. data/lib/celerity/elements/table_elements.rb +1 -1
  31. data/lib/celerity/elements/table_row.rb +5 -5
  32. data/lib/celerity/elements/text_field.rb +33 -28
  33. data/lib/celerity/exception.rb +11 -5
  34. data/lib/celerity/htmlunit.rb +24 -8
  35. data/lib/celerity/htmlunit/commons-codec-1.4.jar +0 -0
  36. data/lib/celerity/htmlunit/htmlunit-2.6.jar +0 -0
  37. data/lib/celerity/htmlunit/htmlunit-core-js-2.6.jar +0 -0
  38. data/lib/celerity/htmlunit/nekohtml-1.9.13.jar +0 -0
  39. data/lib/celerity/htmlunit/{xercesImpl-2.8.1.jar → xercesImpl-2.9.1.jar} +0 -0
  40. data/lib/celerity/ignoring_web_connection.rb +15 -0
  41. data/lib/celerity/input_element.rb +1 -1
  42. data/lib/celerity/listener.rb +23 -17
  43. data/lib/celerity/short_inspect.rb +20 -0
  44. data/lib/celerity/util.rb +5 -2
  45. data/lib/celerity/version.rb +3 -10
  46. data/lib/celerity/viewer_connection.rb +89 -0
  47. data/lib/celerity/watir_compatibility.rb +2 -5
  48. data/lib/celerity/xpath_support.rb +48 -0
  49. data/spec/browser_authentication_spec.rb +16 -0
  50. data/spec/browser_spec.rb +300 -0
  51. data/spec/clickable_element_spec.rb +39 -0
  52. data/spec/default_viewer_spec.rb +23 -0
  53. data/spec/element_spec.rb +51 -0
  54. data/spec/filefield_spec.rb +18 -0
  55. data/spec/htmlunit_spec.rb +56 -0
  56. data/spec/index_offset_spec.rb +24 -0
  57. data/spec/listener_spec.rb +142 -0
  58. data/spec/spec_helper.rb +8 -0
  59. data/tasks/benchmark.rake +4 -0
  60. data/tasks/deployment.rake +43 -0
  61. data/tasks/environment.rake +7 -0
  62. data/tasks/fix.rake +25 -0
  63. data/tasks/jar.rake +4 -6
  64. data/tasks/rspec.rake +43 -0
  65. data/tasks/simple_ci.rake +94 -0
  66. data/tasks/snapshot.rake +22 -0
  67. data/tasks/website.rake +17 -0
  68. data/tasks/yard.rake +9 -0
  69. metadata +59 -26
  70. data/README.txt +0 -69
  71. data/lib/celerity/extra/method_generator.rb +0 -170
  72. data/lib/celerity/htmlunit/commons-codec-1.3.jar +0 -0
  73. data/lib/celerity/htmlunit/htmlunit-2.5-SNAPSHOT.jar +0 -0
  74. data/lib/celerity/htmlunit/htmlunit-core-js-2.5-SNAPSHOT.jar +0 -0
  75. data/lib/celerity/htmlunit/nekohtml-1.9.12-20090308.130127-11.jar +0 -0
@@ -0,0 +1,15 @@
1
+ module Celerity
2
+ class IgnoringWebConnection < HtmlUnit::Util::FalsifyingWebConnection
3
+
4
+ def initialize(web_client, pattern)
5
+ super(web_client)
6
+ @pattern = pattern
7
+ end
8
+
9
+ def getResponse(request_settings)
10
+ return super unless request_settings.getUrl.toString =~ @pattern
11
+ createWebResponse(request_settings, "", "text/html")
12
+ end
13
+
14
+ end
15
+ end
@@ -9,7 +9,7 @@ module Celerity
9
9
 
10
10
  def readonly?
11
11
  assert_exists
12
- @object.isAttributeDefined('readonly')
12
+ @object.hasAttribute 'readonly'
13
13
  end
14
14
 
15
15
  private
@@ -3,7 +3,7 @@ module Celerity
3
3
  #
4
4
  # This class is used to wrap some of the listeners available from HtmlUnit's WebClient.
5
5
  #
6
-
6
+
7
7
  class Listener
8
8
  include com.gargoylesoftware.htmlunit.AlertHandler
9
9
  include com.gargoylesoftware.htmlunit.ConfirmHandler
@@ -18,12 +18,12 @@ module Celerity
18
18
  @webclient = webclient
19
19
  @procs = Hash.new { |h, k| h[k] = [] }
20
20
  end
21
-
21
+
22
22
  #
23
23
  # Add a listener block for one of the available types.
24
24
  # @see Celerity::Browser#add_listener
25
25
  #
26
-
26
+
27
27
  def add_listener(type, &block)
28
28
  case type
29
29
  when :status
@@ -63,51 +63,57 @@ module Celerity
63
63
  raise TypeError, "must give proc or index"
64
64
  end
65
65
  end
66
-
66
+
67
67
  #
68
68
  # interface StatusHandler
69
69
  #
70
-
70
+
71
71
  def statusMessageChanged(page, message)
72
72
  @procs[:status].each { |h| h.call(page, message) }
73
73
  end
74
-
74
+
75
75
  #
76
76
  # interface AlertHandler
77
77
  #
78
-
78
+
79
79
  def handleAlert(page, message)
80
80
  @procs[:alert].each { |h| h.call(page, message) }
81
81
  end
82
-
82
+
83
83
  #
84
84
  # interface ConfirmHandler
85
85
  #
86
-
86
+ # The returned value is determined by the last registered :confirm listener proc.
87
+ # If it is nil, return true, otherwise return that value as a boolean.
88
+ #
89
+ # @see Browser#confirm
90
+ #
91
+
87
92
  def handleConfirm(page, message)
88
- @procs[:confirm].each { |h| h.call(page, message) }
93
+ val = @procs[:confirm].map { |h| h.call(page, message) }.last
94
+ val.nil? || !!val
89
95
  end
90
96
 
91
97
  #
92
98
  # interface AttachmentHandler
93
99
  #
94
-
100
+
95
101
  def handleAttachment(page)
96
102
  @procs[:attachment].each { |h| h.call(page) }
97
103
  end
98
-
104
+
99
105
  #
100
106
  # interface PromptHandler
101
107
  #
102
-
108
+
103
109
  def handlePrompt(page, message)
104
110
  @procs[:prompt].each { |h| h.call(page, message) }
105
111
  end
106
-
112
+
107
113
  #
108
114
  # interface WebWindowListener
109
115
  #
110
-
116
+
111
117
  def webWindowClosed(web_window_event)
112
118
  @procs[:web_window_event].each { |h| h.call(web_window_event) }
113
119
  end
@@ -117,7 +123,7 @@ module Celerity
117
123
  #
118
124
  # interface HTMLParserListener
119
125
  #
120
-
126
+
121
127
  def error(message, url, line, column, key)
122
128
  @procs[:html_parser].each { |h| h.call(message, url, line, column, key) }
123
129
  end
@@ -126,7 +132,7 @@ module Celerity
126
132
  #
127
133
  # interface IncorrectnessListener
128
134
  #
129
-
135
+
130
136
  def notify(message, origin)
131
137
  @procs[:incorrectness].each { |h| h.call(message, origin) }
132
138
  end
@@ -0,0 +1,20 @@
1
+ module Celerity
2
+ module ShortInspect
3
+
4
+ def short_inspect(opts)
5
+ if excluded_ivars = opts[:exclude]
6
+ ivars = (instance_variables - excluded_ivars)
7
+ elsif included_ivars = opts[:include]
8
+ ivars = included_ivars
9
+ else
10
+ raise ArgumentError, "unknown arg: #{opts.inspect}"
11
+ end
12
+
13
+ ivars.map! { |ivar| "#{ivar}=#{instance_variable_get(ivar).inspect}" }
14
+ '#<%s:0x%s %s>' % [self.class.name, self.hash.to_s(16), ivars.join(" ")]
15
+ end
16
+
17
+
18
+
19
+ end
20
+ end
data/lib/celerity/util.rb CHANGED
@@ -28,7 +28,6 @@ module Celerity
28
28
  HtmlUnit::Html::HtmlHiddenInput => Celerity::Hidden,
29
29
  HtmlUnit::Html::HtmlImage => Celerity::Image,
30
30
  HtmlUnit::Html::HtmlLabel => Celerity::Label,
31
- HtmlUnit::Html::HtmlLink => Celerity::Link,
32
31
  HtmlUnit::Html::HtmlListItem => Celerity::Li,
33
32
  HtmlUnit::Html::HtmlMap => Celerity::Map,
34
33
  HtmlUnit::Html::HtmlOption => Celerity::Option,
@@ -58,7 +57,7 @@ module Celerity
58
57
  # HtmlUnit will recognize most common file types, but custom ones can be added here.
59
58
  # Used for FileField uploads.
60
59
  #
61
-
60
+
62
61
  ContentTypes = {
63
62
  ".bmp" => "image/x-ms-bmp",
64
63
  ".doc" => "application/msword",
@@ -84,5 +83,9 @@ module Celerity
84
83
  strip
85
84
  end
86
85
 
86
+ def logger_for(package_string)
87
+ java.util.logging.Logger.getLogger(package_string)
88
+ end
89
+
87
90
  end
88
91
  end
@@ -1,10 +1,3 @@
1
- module Celerity #:nodoc:
2
- module VERSION #:nodoc:
3
- MAJOR = 0
4
- MINOR = 0
5
- TINY = 6
6
- PATCH = nil # Set to nil for official release
7
-
8
- STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
9
- end
10
- end
1
+ module Celerity
2
+ VERSION = "0.0.7"
3
+ end
@@ -0,0 +1,89 @@
1
+ module Celerity
2
+ class ViewerConnection
3
+
4
+ #
5
+ # Create a new connection to the given host/port
6
+ #
7
+
8
+ def self.create(host, port)
9
+ # if the connection fails, we won't spend time loading json
10
+ socket = TCPSocket.new(host, port)
11
+ require "json"
12
+ new(socket)
13
+ end
14
+
15
+ def initialize(socket)
16
+ @socket = socket
17
+ end
18
+
19
+ #
20
+ # Tells the viewer to render the given HTML, with the given URL as base url.
21
+ #
22
+
23
+ def render_html(html, url)
24
+ send_data('method' => 'page_changed', 'html' => html, 'url' => url)
25
+ end
26
+
27
+ #
28
+ # Tells the viewer to save a screenshot of the current page to the given path.
29
+ # May not be available on all viewers.
30
+ #
31
+
32
+ def save(path)
33
+ send_data('method' => 'save', 'path' => path)
34
+ end
35
+
36
+
37
+ #
38
+ # Tells the viewer to dump the render tree to the given path.
39
+ # Only available in the Qt viewer.
40
+ #
41
+
42
+ def save_render_tree(path)
43
+ send_data('method' => 'save_render_tree', 'path' => path)
44
+ end
45
+
46
+ #
47
+ # Get the currently rendered page as a Base64-encoded PNG image.
48
+ # Only available in the Qt viewer.
49
+ #
50
+
51
+ def image_data
52
+ send_data('method' => 'image_data')
53
+ data = read_data
54
+ data['image'] || data['error']
55
+ end
56
+
57
+ #
58
+ # Close the connection.
59
+ #
60
+
61
+ def close
62
+ @socket.close rescue nil
63
+ end
64
+
65
+ private
66
+
67
+ def send_data(msg)
68
+ json = msg.to_json
69
+ data = "Content-Length: #{json.size}\n\n#{json}"
70
+ @socket.write data
71
+ @socket.flush
72
+
73
+ nil
74
+ end
75
+
76
+ def read_data
77
+ buf = ''
78
+ until buf =~ /\n\n\z/ || @socket.eof? || @socket.closed?
79
+ buf << @socket.read(1).to_s
80
+ end
81
+
82
+ return if buf.empty?
83
+
84
+ length = buf[/Content-Length: (\d+)/, 1].to_i
85
+ JSON.parse @socket.read(length)
86
+ end
87
+
88
+ end
89
+ end
@@ -1,7 +1,7 @@
1
1
  module Celerity
2
2
  class Browser
3
3
  class << self
4
-
4
+
5
5
  # Added for Watir compatibility - not in use by Celerity
6
6
  attr_accessor :speed, :attach_timeout, :visible
7
7
  # Added for Watir compatibility - not in use by Celerity
@@ -25,8 +25,6 @@ module Celerity
25
25
  def bring_to_front; true; end
26
26
  # Added for Watir compatibility - not in use by Celerity
27
27
  def speed=(s); s end
28
- # Added for Watir compatibility - not in use by Celerity
29
- def status; '' end
30
28
  end
31
29
 
32
30
 
@@ -70,7 +68,6 @@ module Celerity
70
68
  alias_method :getAllContents, :options
71
69
  alias_method :clearSelection, :clear
72
70
  alias_method :clear_selection, :clear
73
- alias_method :select_value, :select
74
71
  alias_method :includes?, :include?
75
72
  end
76
73
 
@@ -78,7 +75,7 @@ module Celerity
78
75
  alias_method :dragContentsTo, :drag_contents_to
79
76
  alias_method :getContents, :value
80
77
  alias_method :get_contents, :value
81
-
78
+
82
79
  def requires_typing; end
83
80
  end
84
81
  end
@@ -0,0 +1,48 @@
1
+ module Celerity
2
+
3
+ #
4
+ # Module to search by xpath
5
+ #
6
+
7
+ module XpathSupport
8
+
9
+ #
10
+ # Get the first element found matching the given XPath.
11
+ #
12
+ # @param [String] xpath
13
+ # @return [Celerity::Element] An element subclass (or Element if none is found)
14
+ #
15
+
16
+ def element_by_xpath(xpath)
17
+ assert_exists
18
+ obj = @page.getFirstByXPath(xpath)
19
+ element_from_dom_node(obj)
20
+ end
21
+
22
+ #
23
+ # Get all the elements matching the given XPath.
24
+ #
25
+ # @param [String] xpath
26
+ # @return [Array<Celerity::Element>] array of elements
27
+ #
28
+
29
+ def elements_by_xpath(xpath)
30
+ assert_exists
31
+ objects = @page.getByXPath(xpath)
32
+ # should use an ElementCollection here?
33
+ objects.map { |o| element_from_dom_node(o) }.compact
34
+ end
35
+
36
+ #
37
+ # Convert the given HtmlUnit DomNode to a Celerity object
38
+ #
39
+
40
+ def element_from_dom_node(obj)
41
+ element_class = Util.htmlunit2celerity(obj.class) || Element
42
+ element_class.new(self, :object, obj)
43
+ end
44
+
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/watirspec/spec_helper'
2
+
3
+ describe "Browser" do
4
+
5
+ describe "#credentials=" do
6
+ it "sets the basic authentication credentials" do
7
+ browser.goto(WatirSpec.host + "/authentication")
8
+ browser.text.should_not include("ok")
9
+
10
+ browser.credentials = "foo:bar"
11
+
12
+ browser.goto(WatirSpec.host + "/authentication")
13
+ browser.text.should include("ok")
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,300 @@
1
+ require File.dirname(__FILE__) + '/watirspec/spec_helper'
2
+
3
+ describe "Browser" do
4
+ describe "#new" do
5
+ it "raises TypeError if argument is not a Hash" do
6
+ lambda { Browser.new(:foo) }.should raise_error(TypeError)
7
+ end
8
+
9
+ it "raises ArgumentError if given bad arguments for :render key" do
10
+ lambda { Browser.new(:render => :foo) }.should raise_error(ArgumentError)
11
+ end
12
+
13
+ it "raises ArgumentError if given bad arguments for :browser key" do
14
+ lambda { Browser.new(:browser => 'foo') }.should raise_error(ArgumentError)
15
+ end
16
+
17
+ it "raises ArgumentError if given an unknown option" do
18
+ lambda { Browser.new(:foo => 1) }.should raise_error(ArgumentError)
19
+ end
20
+
21
+ it "should hold the init options" do
22
+ browser.options.should == WatirSpec.browser_args.first
23
+ end
24
+
25
+ it "should use the specified proxy" do
26
+ # TODO: find a better way to test this with rack
27
+ require 'webrick/httpproxy'
28
+
29
+ received = false
30
+ blk = lambda { received = true }
31
+ s = WEBrick::HTTPProxyServer.new(:Port => 2001, :ProxyContentHandler => blk)
32
+ Thread.new { s.start }
33
+
34
+ b = Browser.new(WatirSpec.browser_args.first.merge(:proxy => "localhost:2001"))
35
+ b.goto(WatirSpec.host)
36
+ s.shutdown
37
+
38
+ received.should be_true
39
+ end
40
+
41
+ it "should use the specified user agent" do
42
+ b = Browser.new(WatirSpec.browser_args.first.merge(:user_agent => "Celerity"))
43
+ b.goto(WatirSpec.host + "/header_echo")
44
+ b.text.should include('"HTTP_USER_AGENT"=>"Celerity"')
45
+ b.close
46
+ end
47
+
48
+ it "does not try to find a viewer if created with :viewer => false" do
49
+ ViewerConnection.should_not_receive(:create)
50
+
51
+ b = Browser.new(:viewer => false)
52
+ b.close
53
+ end
54
+
55
+ it "tries to find a viewer if created with :viewer => nil" do
56
+ ViewerConnection.should_receive(:create).with("127.0.0.1", 6429)
57
+
58
+ b = Browser.new(:viewer => nil)
59
+ b.close
60
+ end
61
+
62
+ it "tries to find a viewer on the specified host/port with :viewer => String" do
63
+ ViewerConnection.should_receive(:create).with("localhost", 1234)
64
+
65
+ b = Browser.new(:viewer => "localhost:1234")
66
+ b.close
67
+ end
68
+ end
69
+
70
+ describe "#html" do
71
+ %w(shift_jis iso-2022-jp euc-jp).each do |charset|
72
+ it "returns decoded #{charset.upcase} when :charset specified" do
73
+ browser = Browser.new(WatirSpec.browser_args.first.merge(:charset => charset.upcase))
74
+ browser.goto(WatirSpec.files + "/#{charset}_text.html")
75
+ # Browser#text is automagically transcoded into the right charset, but Browser#html isn't.
76
+ browser.html.should =~ /本日は晴天なり。/
77
+ browser.close
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "#response_headers" do
83
+ it "returns the response headers (as a hash)" do
84
+ browser.goto(WatirSpec.host + "/non_control_elements.html")
85
+ browser.response_headers.should be_kind_of(Hash)
86
+ browser.response_headers['Date'].should be_kind_of(String)
87
+ browser.response_headers['Content-Type'].should be_kind_of(String)
88
+ end
89
+ end
90
+
91
+ describe "#content_type" do
92
+ it "returns the content type" do
93
+ browser.goto(WatirSpec.host + "/non_control_elements.html")
94
+ browser.content_type.should =~ /\w+\/\w+/
95
+ end
96
+ end
97
+
98
+ describe "#io" do
99
+ it "returns the io object of the content" do
100
+ browser.goto(WatirSpec.files + "/non_control_elements.html")
101
+ browser.io.should be_kind_of(IO)
102
+ browser.io.read.should == File.read("#{WatirSpec.html}/non_control_elements.html")
103
+ end
104
+ end
105
+
106
+ describe "#goto" do
107
+ it "raises UnexpectedPageException if the content type is not understood" do
108
+ lambda { browser.goto(WatirSpec.host + "/octet_stream") }.should raise_error(UnexpectedPageException)
109
+ end
110
+ end
111
+
112
+ describe "#cookies" do
113
+ it "returns set cookies as a Ruby hash" do
114
+ cookies = browser.cookies
115
+ cookies.should be_instance_of(Hash)
116
+ cookies.should be_empty
117
+
118
+ browser.goto(WatirSpec.host + "/set_cookie")
119
+
120
+ cookies = browser.cookies
121
+ cookies.size.should == 1
122
+ cookies[WatirSpec::Server.host]['monster'].should == "/"
123
+ end
124
+ end
125
+
126
+ describe "#clear_cookies" do
127
+ it "clears all cookies" do
128
+ b = WatirSpec.new_browser
129
+ b.cookies.should be_empty
130
+
131
+ b.goto(WatirSpec.host + "/set_cookie")
132
+ b.cookies.size.should == 1
133
+ b.clear_cookies
134
+ b.cookies.should be_empty
135
+
136
+ b.close
137
+ end
138
+ end
139
+
140
+ describe "add_cookie" do
141
+ it "adds a cookie with the given domain, name and value" do
142
+ browser.add_cookie("example.com", "foo", "bar")
143
+ cookies = browser.cookies
144
+ cookies.should be_instance_of(Hash)
145
+ cookies.should have_key('example.com')
146
+ cookies['example.com']['foo'].should == 'bar'
147
+
148
+ browser.clear_cookies
149
+ end
150
+
151
+ it "adds a cookie with the specified options" do
152
+ browser.add_cookie("example.com", "foo", "bar", :path => "/foobar", :max_age => 1000)
153
+ cookies = browser.cookies
154
+ cookies.should be_instance_of(Hash)
155
+ cookies['example.com']['foo'].should == 'bar'
156
+ end
157
+ end
158
+
159
+ describe "remove_cookie" do
160
+ it "removes the cookie for the given domain and name" do
161
+ b = WatirSpec.new_browser
162
+ b.goto(WatirSpec.host + "/set_cookie")
163
+
164
+ b.remove_cookie(WatirSpec::Server.host, "monster")
165
+ b.cookies.should be_empty
166
+
167
+ b.close
168
+ end
169
+
170
+ it "raises an error if no such cookie exists" do
171
+ lambda { browser.remove_cookie("bogus.com", "bar") }.should raise_error(CookieNotFoundError)
172
+ end
173
+ end
174
+
175
+ describe "#wait" do
176
+ it "should wait for javascript timers to finish" do
177
+ alerts = 0
178
+ browser.add_listener(:alert) { alerts += 1 }
179
+ browser.goto(WatirSpec.files + "/timeout.html")
180
+ browser.div(:id, 'alert').click
181
+ browser.wait.should be_true
182
+ alerts.should == 1
183
+ end
184
+ end
185
+
186
+ describe "#wait_while" do
187
+ it "waits until the specified condition becomes false" do
188
+ browser.goto(WatirSpec.files + "/timeout.html")
189
+ browser.div(:id, "change").click
190
+ browser.wait_while { browser.contains_text("Trigger change") }
191
+ browser.div(:id, "change").text.should == "all done"
192
+ end
193
+
194
+ it "returns the value returned from the block" do
195
+ browser.wait_while { false }.should == false
196
+ end
197
+ end
198
+
199
+ describe "#wait_until" do
200
+ it "waits until the condition becomes true" do
201
+ browser.goto(WatirSpec.files + "/timeout.html")
202
+ browser.div(:id, "change").click
203
+ browser.wait_until { browser.contains_text("all done") }
204
+ end
205
+
206
+ it "returns the value returned from the block" do
207
+ browser.wait_until { true }.should == true
208
+ end
209
+ end
210
+
211
+ describe "#element_by_xpath" do
212
+ it "returns usable elements even though they're not supported" do
213
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
214
+
215
+ el = browser.element_by_xpath("//link")
216
+ el.should be_instance_of(Celerity::Element)
217
+ el.rel.should == "stylesheet"
218
+ end
219
+ end
220
+
221
+ describe "#focused_element" do
222
+ it "returns the element that currently has the focus" do
223
+ b = WatirSpec.new_browser
224
+ b.goto(WatirSpec.files + "/forms_with_input_elements.html")
225
+ b.focused_element.id.should == "new_user_first_name"
226
+
227
+ b.close
228
+ end
229
+ end
230
+
231
+ describe "#status_code" do
232
+ it "returns the status code of the last request" do
233
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
234
+ browser.status_code.should == 200
235
+
236
+ browser.goto(WatirSpec.host + "/doesnt_exist")
237
+ browser.status_code.should == 404
238
+ end
239
+ end
240
+
241
+ describe "#status_code_exceptions" do
242
+ it "raises status code exceptions if set to true" do
243
+ browser.status_code_exceptions = true
244
+ lambda do
245
+ browser.goto(WatirSpec.host + "/doesnt_exist")
246
+ end.should raise_error(NavigationException)
247
+ end
248
+ end
249
+
250
+ describe "#javascript_exceptions" do
251
+ it "raises javascript exceptions if set to true" do
252
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
253
+ browser.javascript_exceptions = true
254
+ lambda do
255
+ browser.execute_script("no_such_function()")
256
+ end.should raise_error
257
+ end
258
+ end
259
+
260
+ describe "#add_listener" do
261
+ it "should click OK for confirm() calls" do
262
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
263
+ browser.add_listener(:confirm) { }
264
+ browser.execute_script("confirm()").should == true
265
+ end
266
+ end
267
+
268
+ describe "#add_checker" do
269
+
270
+ # watir only supports a lambda instance as argument, celerity supports both
271
+ it "runs the given block on each page load" do
272
+ output = ''
273
+
274
+ browser.add_checker { |browser| output << browser.text }
275
+ browser.goto(WatirSpec.files + "/non_control_elements.html")
276
+
277
+ output.should include('Dubito, ergo cogito, ergo sum')
278
+ end
279
+ end
280
+
281
+
282
+ describe "#confirm" do
283
+ it "clicks 'OK' for a confirm() call" do
284
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
285
+
286
+ browser.confirm(true) do
287
+ browser.execute_script('confirm()').should be_true
288
+ end
289
+ end
290
+
291
+ it "clicks 'cancel' for a confirm() call" do
292
+ browser.goto(WatirSpec.files + "/forms_with_input_elements.html")
293
+
294
+ browser.confirm(false) do
295
+ browser.execute_script('confirm()').should be_false
296
+ end
297
+ end
298
+ end
299
+
300
+ end