selenium-client 1.2.3 → 1.2.4

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