selenium-client 1.2.3 → 1.2.4

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.
@@ -16,22 +16,35 @@ Install It
16
16
  Features
17
17
  ========
18
18
 
19
- * Backward compatible with the old-fashioned, XSL generated Selenium Ruby API.
20
- See [the generated driver](http://selenium-client.rubyforge.org/classes/Selenium/Client/GeneratedDriver.html) to get an extensive reference.
19
+ * Backward compatible with the old-fashioned, XSL generated Selenium Ruby API.
20
+ See [the generated driver](http://selenium-client.rubyforge.org/classes/Selenium/Client/GeneratedDriver.html) to get an extensive reference.
21
21
 
22
- * Idiomatic interface to the Selenium API.
22
+ * Idiomatic interface to the Selenium API.
23
23
  See [the Idiomatic module](http://selenium-client.rubyforge.org/classes/Selenium/Client/Idiomatic.html)
24
24
  for more details.
25
25
 
26
- * Convenience methods for AJAX.
27
- See the [Extensions](http://selenium-client.rubyforge.org/classes/Selenium/Client/Extensions.html)
28
- for more details.
29
-
30
- * Leveraging latest innovations in Selenium Remote Control (screenshots, log captures, ...)
26
+ * Convenience methods for AJAX.
27
+ See the [Extensions](http://selenium-client.rubyforge.org/classes/Selenium/Client/Extensions.html)
28
+ for more details.
29
+
30
+ * Flexible wait semantics inline with the trigerring action. e.g.
31
31
 
32
- * Robust Rake task to start/stop the Selenium Remote Control server. More details in the next section.
32
+ * `click 'the_button_id', :wait_for => :page`
33
+ * `click 'the_button_id', :wait_for => :ajax`
34
+ * `click 'the_button_id', :wait_for => :element, :element => 'new_element_id'`
35
+ * `click 'the_button_id', :wait_for => :no_element, :element => 'disappearing_element_id'`
36
+ * `click 'the_button_id', :wait_for => :text, :text => 'New Text'`
37
+ * `click 'the_button_id', :wait_for => :no_text, :text => 'Disappearing Text'`
38
+ * `click 'the_button_id', :wait_for => :effects`
39
+ * `click 'the_button_id', :wait_for => :condition, :javascript => "some arbitrary javascript expression"`
33
40
 
34
- * State-of-the-art reporting for RSpec.
41
+ Check out the `click`, `go_back` and `wait_for` methods of the [Idiomatic Module](http://selenium-client.rubyforge.org/classes/Selenium/Client/Idiomatic.html)
42
+
43
+ * Leveraging latest innovations in Selenium Remote Control (screenshots, log captures, ...)
44
+
45
+ * Robust Rake task to start/stop the Selenium Remote Control server. More details in the next section.
46
+
47
+ * State-of-the-art reporting for RSpec.
35
48
 
36
49
  Plain API
37
50
  =========
@@ -131,8 +144,9 @@ Writing Tests
131
144
  selenium_driver.start_new_browser_session
132
145
  end
133
146
 
134
- after(:each) do
135
- selenium_driver.close_current_browser_session
147
+ # The system capture need to happen BEFORE closing the Selenium session
148
+ config.append_after(:each) do
149
+ @selenium_driver.close_current_browser_session
136
150
  end
137
151
 
138
152
  it "can find Selenium" do
@@ -202,6 +216,21 @@ Grid](http://selenium-grid.openqa.org))
202
216
 
203
217
  You can then get cool reports like [this one](http://ph7spot.com/examples/selenium_rspec_report.html)
204
218
 
219
+ Contribute and Join the Fun!
220
+ ============================
221
+
222
+ We welcome new features, add-ons, bug fixes, example, documentation, etc. Make the gem work the way you
223
+ envision!
224
+
225
+ * I recommend cloning the selenium-client [reference repository](http://github.com/ph7/selenium-client/tree/master)
226
+ I you are more of a SVN guy, the same code also lives at [OpenQA](http://svn.openqa.org/svn/selenium-rc/trunk/clients/ruby)
227
+
228
+ * You can also check out the [RubyForge page](http://rubyforge.org/projects/selenium-client) and the [RDoc](http://selenium-client.rubyforge.org)
229
+
230
+ * We also have a [continuous integration server](http://xserve.openqa.org:8080/view/Ruby%20Client)
231
+
205
232
 
233
+
234
+
206
235
 
207
236
 
@@ -9,6 +9,8 @@ module Selenium
9
9
  include Selenium::Client::GeneratedDriver
10
10
  include Selenium::Client::Extensions
11
11
  include Selenium::Client::Idiomatic
12
+
13
+ attr_reader :browser_string
12
14
 
13
15
  def initialize(server_host, server_port, browser_string, browser_url, timeout_in_seconds=300)
14
16
  @server_host = server_host
@@ -4,52 +4,69 @@ module Selenium
4
4
  # Convenience methods not explicitely part of the protocol
5
5
  module Extensions
6
6
 
7
- # These for all Ajax request to finish (Only works if you are using prototype)
7
+ # These for all Ajax request to finish (Only works if you are using prototype, the wait in happenning browser side)
8
8
  #
9
9
  # See http://davidvollbracht.com/2008/6/4/30-days-of-tech-day-3-waitforajax for
10
10
  # more background.
11
- def wait_for_ajax(timeout=nil)
12
- selenium.wait_for_condition "selenium.browserbot.getCurrentWindow().Ajax.activeRequestCount == 0",
13
- timeout || default_timeout_in_seconds
11
+ def wait_for_ajax(timeout_in_seconds=nil)
12
+ selenium.wait_for_condition "selenium.browserbot.getCurrentWindow().Ajax.activeRequestCount == 0", timeout_in_seconds
14
13
  end
15
14
 
16
- # Wait for all Prototype effects to be processed
15
+ # Wait for all Prototype effects to be processed (the wait in happenning browser side).
17
16
  #
18
17
  # Credits to http://github.com/brynary/webrat/tree/master
19
- def wait_for_effects(timeout=nil)
20
- selenium.wait_for_condition "window.Effect.Queue.size() == 0", timeout || default_timeout_in_seconds
18
+ def wait_for_effects(timeout_in_seconds=nil)
19
+ selenium.wait_for_condition "window.Effect.Queue.size() == 0", timeout_in_seconds
21
20
  end
22
21
 
23
- def wait_for_element(field_name, time=60000)
22
+ # Wait for an element to be present (the wait in happenning browser side).
23
+ def wait_for_element(locator, timeout_in_seconds=nil)
24
24
  script = <<-EOS
25
25
  var element;
26
26
  try {
27
- element = selenium.browserbot.findElement('#{field_name}');
27
+ element = selenium.browserbot.findElement('#{locator}');
28
28
  } catch(e) {
29
29
  element = null;
30
30
  }
31
31
  element != null
32
32
  EOS
33
33
 
34
- wait_for_condition script, time
34
+ wait_for_condition script, timeout_in_seconds
35
35
  end
36
36
 
37
- def wait_for_text(field_name, text, time=60000)
37
+ # Wait for an element to NOT be present (the wait in happenning browser side).
38
+ def wait_for_no_element(locator, timeout_in_seconds=nil)
39
+ script = <<-EOS
40
+ var element;
41
+ try {
42
+ element = selenium.browserbot.findElement('#{locator}');
43
+ } catch(e) {
44
+ element = null;
45
+ }
46
+ element == null
47
+ EOS
48
+
49
+ wait_for_condition script, timeout_in_seconds
50
+ end
51
+
52
+ # Wait for some text to be present (the wait in happenning browser side).
53
+ def wait_for_text(locator, text, timeout_in_seconds=nil)
38
54
  script = "var element;
39
55
  try {
40
- element = selenium.browserbot.findElement('#{field_name}');
56
+ element = selenium.browserbot.findElement('#{locator}');
41
57
  } catch(e) {
42
58
  element = null;
43
59
  }
44
60
  element != null && element.innerHTML == '#{text}'"
45
61
 
46
- wait_for_condition script, time
62
+ wait_for_condition script, timeout_in_seconds
47
63
  end
48
64
 
49
- def wait_for_text_change(field_name, original_text, time=60000)
65
+ # Wait for some text to NOT be present (the wait in happenning browser side).
66
+ def wait_for_no_text(locator, original_text, timeout_in_seconds=nil)
50
67
  script = "var element;
51
68
  try {
52
- element = selenium.browserbot.findElement('#{field_name}');
69
+ element = selenium.browserbot.findElement('#{locator}');
53
70
  } catch(e) {
54
71
  element = null;
55
72
  }
@@ -58,16 +75,17 @@ module Selenium
58
75
  wait_for_condition script, time
59
76
  end
60
77
 
61
- def wait_for_field_value(field_name, value, time=60000)
78
+ # Wait for a field to get a specific value (the wait in happenning browser side).
79
+ def wait_for_field_value(locator, expected_value, timeout_in_seconds=nil)
62
80
  script = "var element;
63
81
  try {
64
- element = selenium.browserbot.findElement('#{field_name}');
82
+ element = selenium.browserbot.findElement('#{locator}');
65
83
  } catch(e) {
66
84
  element = null;
67
85
  }
68
- element != null && element.value == '#{value}'"
86
+ element != null && element.value == '#{expected_value}'"
69
87
 
70
- wait_for_condition script, time
88
+ wait_for_condition script, timeout_in_seconds
71
89
  end
72
90
 
73
91
  end
@@ -14,7 +14,7 @@ module Selenium
14
14
  # or the innerText (IE-like browsers) of the element, which is the
15
15
  # rendered text shown to the user.
16
16
  #
17
- # 'locator' is an Selenium element locator
17
+ # * 'locator' is an Selenium element locator
18
18
  def text_content(locator)
19
19
  string_command"getText", [locator,]
20
20
  end
@@ -37,44 +37,84 @@ module Selenium
37
37
  # if you want to wait for a page to load, you must wait immediately
38
38
  # after a Selenium command that caused a page-load.
39
39
  #
40
- # 'timeout_in_seconds' is a timeout in seconds, after which this
41
- # command will return with an error
40
+ # * 'timeout_in_seconds' is a timeout in seconds, after which this
41
+ # command will return with an error
42
42
  def wait_for_page(timeout_in_seconds=nil)
43
43
  actual_timeout = timeout_in_seconds || default_timeout_in_seconds
44
44
  remote_control_command "waitForPageToLoad", [actual_timeout * 1000,]
45
45
  end
46
46
 
47
+ # Flexible wait semantics. ait is happening browser side. Useful for testing AJAX application.
48
+ #
49
+ # * wait :wait_for => :page # will wait for a new page to load
50
+ # * wait :wait_for => :ajax # will wait for all ajax requests to be completed (Prototype only)
51
+ # * wait :wait_for => :effects # will wait for all Prototype effects to be rendered
52
+ # * wait :wait_for => :element, :element => 'new_element_id' # will wait for an element to be present/appear
53
+ # * wait :wait_for => :no_element, :element => 'new_element_id' # will wait for an element to be not be present/disappear
54
+ # * wait :wait_for => :text, :text => 'some text' # will wait for some text to be present/appear
55
+ # * wait :wait_for => :no_text, :text => 'some text' # will wait for the text to be not be present/disappear
56
+ # * wait :wait_for => :condition, :javascript => 'some expression' # will wait for the javascript expression to be true
57
+ #
58
+ # Using options you can also define an explicit timeout (:timeout_in_seconds key). Otherwise the default driver timeout
59
+ # is used.
60
+ def wait_for(options)
61
+ if options[:wait_for] == :page
62
+ wait_for_page options[:timeout_in_seconds]
63
+ elsif options[:wait_for] == :ajax
64
+ wait_for_ajax options[:timeout_in_seconds]
65
+ elsif options[:wait_for] == :element
66
+ wait_for_element options[:element], options[:timeout_in_seconds]
67
+ elsif options[:wait_for] == :no_element
68
+ wait_for_no_element options[:element], options[:timeout_in_seconds]
69
+ elsif options[:wait_for] == :text
70
+ wait_for_text options[:text], options[:timeout_in_seconds]
71
+ elsif options[:wait_for] == :no_text
72
+ wait_for_no_text options[:text], options[:timeout_in_seconds]
73
+ elsif options[:wait_for] == :effects
74
+ wait_for_effects options[:timeout_in_seconds]
75
+ elsif options[:wait_for] == :condition
76
+ wait_for_condition options[:javascript], options[:timeout_in_seconds]
77
+ end
78
+ end
79
+
47
80
  # Gets the entire text of the page.
48
81
  def body_text
49
82
  string_command"getBodyText"
50
83
  end
51
84
 
52
- # Clicks on a link, button, checkbox or radio button. If the click action
53
- # causes a new page to load (like a link usually does), call
54
- # waitForPageToLoad.
85
+ # Clicks on a link, button, checkbox or radio button.
55
86
  #
56
87
  # 'locator' is an element locator
88
+ #
89
+ # Using 'options' you can automatically wait for an event to happen after the
90
+ # click. e.g.
91
+ #
92
+ # * click 'some_id', :wait_for => :page # will wait for a new page to load
93
+ # * click 'some_id', :wait_for => :ajax # will wait for all ajax requests to be completed (Prototype only)
94
+ # * click 'some_id', :wait_for => :effects # will wait for all Prototype effects to be rendered
95
+ # * click 'some_id', :wait_for => :element, :element => 'new_element_id' # will wait for an element to be present/appear
96
+ # * click 'some_id', :wait_for => :no_element, :element => 'new_element_id' # will wait for an element to be not be present/disappear
97
+ # * click :wait_for => :text, :text => 'some text' # will wait for some text to be present/appear
98
+ # * click :wait_for => :no_text, :text => 'some text' # will wait for the text to be not be present/disappear
99
+ # * click 'some_id', :wait_for => :condition, :javascript => 'some expression' # will wait for the javascript expression to be true
100
+ #
101
+ # Using options you can also define an explicit timeout (:timeout_in_seconds key). Otherwise the default driver timeout
102
+ # is used.
57
103
  def click(locator, options={})
58
104
  remote_control_command("click", [locator,])
59
- if options[:wait_for] == :page
60
- wait_for_page options[:timeout_in_seconds]
61
- elsif options[:wait_for] == :ajax
62
- wait_for_ajax options[:timeout_in_seconds]
63
- elsif options[:wait_for] == :effects
64
- wait_for_effects options[:timeout_in_seconds]
65
- end
105
+ wait_for options
66
106
  end
67
107
 
68
108
  # Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.
69
109
  #
70
- # 'pattern' is a pattern to match with the text of the page
110
+ # * 'pattern' is a pattern to match with the text of the page
71
111
  def text?(pattern)
72
112
  boolean_command "isTextPresent", [pattern,]
73
113
  end
74
114
 
75
115
  # Verifies that the specified element is somewhere on the page.
76
116
  #
77
- # 'locator' is an element locator
117
+ # * 'locator' is an element locator
78
118
  def element?(locator)
79
119
  boolean_command "isElementPresent", [locator,]
80
120
  end
@@ -84,7 +124,7 @@ module Selenium
84
124
  # For checkbox/radio elements, the value will be "on" or "off"
85
125
  # depending on whether the element is checked or not.
86
126
  #
87
- # 'locator' is an element locator
127
+ # * 'locator' is an element locator
88
128
  def field(locator)
89
129
  string_command "getValue", [locator,]
90
130
  end
@@ -97,7 +137,7 @@ module Selenium
97
137
  # Returns whether a toggle-button (checkbox/radio) is checked.
98
138
  # Fails if the specified element doesn't exist or isn't a toggle-button.
99
139
  #
100
- # 'locator' is an element locator pointing to a checkbox or radio button
140
+ # * 'locator' is an element locator pointing to a checkbox or radio button
101
141
  def checked?(locator)
102
142
  boolean_command "isChecked", [locator,]
103
143
  end
@@ -113,8 +153,10 @@ module Selenium
113
153
  # Getting an alert has the same effect as manually clicking OK. If an
114
154
  # alert is generated but you do not consume it with getAlert, the next Selenium action
115
155
  # will fail.
156
+ #
116
157
  # Under Selenium, JavaScript alerts will NOT pop up a visible alert
117
158
  # dialog.
159
+ #
118
160
  # Selenium does NOT support JavaScript alerts that are generated in a
119
161
  # page's onload() event handler. In this case a visible dialog WILL be
120
162
  # generated and Selenium will hang until someone manually clicks OK.
@@ -181,7 +223,7 @@ module Selenium
181
223
  # a locator to refer to a single element in your application page, you can
182
224
  # use <tt>this.browserbot.findElement("id=foo")</tt> where "id=foo" is your locator.
183
225
  #
184
- # 'script' is the JavaScript snippet to run
226
+ # * 'script' is the JavaScript snippet to run
185
227
  def js_eval(script)
186
228
  string_command"getEval", [script,]
187
229
  end
@@ -200,12 +242,47 @@ module Selenium
200
242
  # Returns the text from a cell of a table. The cellAddress syntax
201
243
  # tableLocator.row.column, where row and column start at 0.
202
244
  #
203
- # 'tableCellAddress' is a cell address, e.g. "foo.1.4"
245
+ # * 'tableCellAddress' is a cell address, e.g. "foo.1.4"
204
246
  def table_cell_text(tableCellAddress)
205
247
  string_command "getTable", [tableCellAddress,]
206
248
  end
207
249
 
208
- # set speed
250
+ # Runs the specified JavaScript snippet repeatedly until it evaluates to "true".
251
+ # The snippet may have multiple lines, but only the result of the last line
252
+ # will be considered.
253
+ #
254
+ # Note that, by default, the snippet will be run in the runner's test window, not in the window
255
+ # of your application. To get the window of your application, you can use
256
+ # the JavaScript snippet <tt>selenium.browserbot.getCurrentWindow()</tt>, and then
257
+ # run your JavaScript in there
258
+ #
259
+ #
260
+ # * 'script' is the JavaScript snippet to run
261
+ # * 'timeout_in_seconds' is a timeout in seconds, after which this command will return with an error
262
+ def wait_for_condition(script, timeout_in_seconds = nil)
263
+ remote_control_command "waitForCondition", [script, (timeout_in_seconds || default_timeout_in_seconds) * 1000,]
264
+ end
265
+
266
+ # Simulates the user clicking the "back" button on their browser.
267
+ # Using 'options' you can automatically wait for an event to happen after the
268
+ # click. e.g.
269
+ #
270
+ # * go_back :wait_for => :page # will wait for a new page to load
271
+ # * go_back :wait_for => :ajax # will wait for all ajax requests to be completed (Prototype only)
272
+ # * go_back :wait_for => :effects # will wait for all Prototype effects to be rendered
273
+ # * go_back :wait_for => :element, :element => 'new_element_id' # will wait for an element to be present/appear
274
+ # * go_back :wait_for => :no_element, :element => 'new_element_id' # will wait for an element to be not be present/disappear
275
+ # * go_back :wait_for => :text, :text => 'some text' # will wait for some text to be present/appear
276
+ # * go_back :wait_for => :no_text, :text => 'some text' # will wait for the text to be not be present/disappear
277
+ # * go_back :wait_for => :condition, :javascript => 'some expression' # will wait for the javascript expression to be true
278
+ #
279
+ # Using options you can also define an explicit timeout (:timeout_in_seconds key). Otherwise the default driver timeout
280
+ # is used.
281
+ def go_back(options={})
282
+ remote_control_command "goBack"
283
+ wait_for options
284
+ end
285
+
209
286
  end
210
287
 
211
288
  end
@@ -7,7 +7,7 @@ require File.expand_path(File.dirname(__FILE__) + "/reporting/selenium_test_repo
7
7
 
8
8
  Spec::Runner.configure do |config|
9
9
 
10
- config.after(:each) do
10
+ config.prepend_after(:each) do
11
11
  begin
12
12
  Selenium::RSpec::SeleniumTestReportFormatter.capture_system_state(selenium_driver, self) if execution_error
13
13
  if selenium_driver.session_started?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenQA
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-29 00:00:00 -07:00
12
+ date: 2008-09-30 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
72
  requirements: []
73
73
 
74
74
  rubyforge_project: selenium-client
75
- rubygems_version: 1.3.0
75
+ rubygems_version: 1.2.0
76
76
  signing_key:
77
77
  specification_version: 2
78
78
  summary: Official Ruby Client for Selenium RC.