honey-do 0.5.0 → 0.6.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.
data/Rakefile CHANGED
@@ -47,7 +47,7 @@ end
47
47
 
48
48
  spec = Gem::Specification.new do |s|
49
49
  s.name = 'honey-do'
50
- s.version = '0.5.0'
50
+ s.version = '0.6.0'
51
51
  s.rubyforge_project = s.name
52
52
 
53
53
  s.platform = Gem::Platform::RUBY
@@ -0,0 +1,2 @@
1
+ @echo off
2
+ java -jar C:\swa\trunk\commerce-project\libs\selenium-server\v1.0b1\selenium-server.jar -multiWindow -userExtensions ..\js\user-extensions.js
Binary file
@@ -0,0 +1,16 @@
1
+ <html>
2
+ <head>
3
+ <title>HoneyDo Demo Form: Just give it a list!</title>
4
+ <script language="JavaScript" src="everything.js"></script>
5
+ </head>
6
+ <body onload="populate_number_list(day_list_form.elements['day_of_month'],1,31,true);">
7
+ <div>
8
+ <form name="day_list_form">
9
+ <table border="3" bgcolor="beige" cellspacing="1" cellpadding="4">
10
+ <tr><td>Day of Month:<br><select name="day_of_month"></select></td></tr>
11
+ <tr><td><input type="reset" value="Reset" name="resetButton"></td></tr>
12
+ </table>
13
+ </form>
14
+ </div>
15
+ </body>
16
+ </html>
@@ -4,18 +4,20 @@
4
4
  <script language="JavaScript" src="everything.js"></script>
5
5
  </head>
6
6
  <body>
7
+
7
8
  <!-- A one-of-everything HTML form:
8
9
  after David Flanagan, Chapter 18 of "JavaScript: The Definitive Guide", O'Reilly, 5th edition
9
10
  -->
10
11
  <div align="center">
11
- <form name="everything" method="POST" action="../display">
12
+ <form name="everything" method="POST" action="../display" >
12
13
  <table border="3" bgcolor="beige" cellspacing="1" cellpadding="4">
13
14
  <tr>
14
- <td colspan="4"><h4>All Possible Form Elements</h4></td>
15
+ <td colspan="5"><h4>All Possible Form Elements</h4></td>
15
16
  </tr>
16
17
  <tr>
17
- <td>Username:<br>[1]<input type="text" name="username" size="15"></td>
18
- <td>Password:<br>[2]<input type="password" name="password" size="15"></td>
18
+ <td>Id Only:<br>[1]<input type="text" id="id_not_name" size="5"></td>
19
+ <td>Username:<br>[1]<input type="text" name="username" id="id_of_username_field" size="15"></td>
20
+ <td>Password:<br>[2]<input type="password" name="password" size="10"></td>
19
21
  <td rowspan="4">Input Events[3]<br>
20
22
  <textarea name="event_reports_area" rows="20" cols="40"></textarea></td>
21
23
  <td rowspan="4" align="center" valign="center">
@@ -25,7 +27,7 @@
25
27
  [13]<input type="hidden" value="you can't see this unless you're looking at the source" name="justHiding"><br></td>
26
28
  </tr>
27
29
  <tr>
28
- <td colspan="2">
30
+ <td colspan="3">
29
31
  Filename: [4]<input type="file" name="file" size="15"> </td>
30
32
  </tr>
31
33
  <tr>
@@ -81,6 +83,7 @@
81
83
  <option value="gold">Gold
82
84
  <option value="zinc">Zinc
83
85
  </select></td>
86
+
84
87
  </tr>
85
88
  </table>
86
89
  </form>
@@ -110,3 +113,5 @@
110
113
  </form>
111
114
  </div>
112
115
  </body>
116
+ </html>
117
+
@@ -52,4 +52,15 @@ function removehandlers(f) {
52
52
  }
53
53
  }
54
54
 
55
- function selectable(type) { return (/^select/i).test(type);}
55
+ function selectable(type) { return (/^select/i).test(type);}
56
+
57
+ function populate_number_list(theObj,minVal,maxVal) {
58
+ var selIdx = 0;
59
+ if (theObj.options.length <= 2) {
60
+ var idx = theObj.options.length;
61
+ for (var i=minVal; i<=maxVal; i++) {
62
+ var label = i;
63
+ theObj.options[idx++] = new Option(label,i);
64
+ }
65
+ }
66
+ }
@@ -16,22 +16,25 @@
16
16
 
17
17
  Form_.FIELD_DELIMITER = '|'
18
18
  Form_.PAIR_DELIMITER = ':::'
19
+
19
20
 
20
- Form_.prototype.set_values = function(big_string, ok_if_not_found){
21
+ Form_.prototype.set_values = function(big_string, ok_if_not_found, select_as_text){
21
22
  var pairs = big_string.split(Form_.FIELD_DELIMITER), pair = [], error_values = '';
22
23
 
23
24
  for(var i = 0; i < pairs.length; i++){
24
25
  pair = pairs[i].split(Form_.PAIR_DELIMITER);
25
- error_values += this.set_value(pair[0], pair[1], ok_if_not_found);
26
+ error_values += this.set_value(pair[0], pair[1], ok_if_not_found, select_as_text);
26
27
  }
27
28
  return error_values;
28
29
  }
29
30
 
30
- Form_.prototype.set_value = function(name, value, ok_if_not_found){
31
+ Form_.prototype.set_value = function(name, value, ok_if_not_found, select_as_text){
31
32
  var error_text = '', e = null;
32
33
  var selectable = /(select-one|select-multiple)/i;
33
34
  var settable = /(text|textarea|password)/i;
34
35
  var clickable = /(button|submit|reset|radio|image)/i;
36
+ Form_.SELECT_AS_TEXT = select_as_text;
37
+
35
38
  try {
36
39
  // if you wanted to do something to explicitly wait for Ajax, you would do it here, before the element lookup
37
40
  e = this.form.elements[name];
@@ -94,7 +97,7 @@
94
97
  }
95
98
 
96
99
  Form_.option_index = function(e, in_value){
97
- if (isNaN(parseInt(in_value))) {
100
+ if (isNaN(parseInt(in_value)) || Form_.SELECT_AS_TEXT) {
98
101
  return Form_.index_of_text(e, in_value);
99
102
  }
100
103
  return in_value; // Todo: 'range' error if index too high
@@ -146,10 +149,7 @@
146
149
  var e = this.form.elements;
147
150
  for(var i = 0; i < e.length; i++){
148
151
  if (e[i].type != 'hidden') {
149
- if (e[i].name)
150
- element_list.push(e[i].name);
151
- else
152
- element_list.push(e[i].value);
152
+ element_list.push(prop_value(e[i], 'name', 'id', 'value'));
153
153
  }
154
154
  }
155
155
  return element_list;
@@ -160,10 +160,7 @@
160
160
  var e = this.form.elements;
161
161
  for(var i = 0; i < e.length; i++){
162
162
  if (!e[i].disabled && e[i].type != 'hidden') {
163
- if (e[i].name)
164
- element_list.push(e[i].name);
165
- else
166
- element_list.push(e[i].value);
163
+ element_list.push(prop_value(e[i], 'name', 'id', 'value'));
167
164
  }
168
165
  }
169
166
  return element_list;
@@ -173,7 +170,7 @@
173
170
  var element_list = [];
174
171
  var e = this.form.elements;
175
172
  for(var i = 0; i < e.length; i++){
176
- element_list.push(e[i].name + '|' + i);
173
+ element_list.push(prop_value(e[i], 'name', 'id') + '|' + i);
177
174
  }
178
175
  return element_list;
179
176
  }
@@ -189,7 +186,7 @@
189
186
 
190
187
  for(var i = 0;i < e.length; i++){
191
188
  if (target_types.test(e[i].type)) {
192
- element_name = e[i].name;
189
+ element_name = prop_value(e[i], 'name', 'id');
193
190
  element_text = e[i].value.custom_trim();
194
191
  if ('selectedIndex' in e[i] && e[i].selectedIndex > -1) {
195
192
  if (e[i].type == 'select-multiple') {
@@ -239,10 +236,7 @@
239
236
  var a = [];
240
237
  var buttons = this.buttons();
241
238
  for(var i = 0; i < buttons.length; i++){
242
- if (buttons[i].name)
243
- a.push(buttons[i].name);
244
- else
245
- a.push(buttons[i].value);
239
+ a.push(prop_value(buttons[i], 'name', 'id', 'value'));
246
240
  }
247
241
  return a;
248
242
  }
@@ -333,6 +327,7 @@
333
327
  return this.replace(special_characters, '\\$1');
334
328
  }
335
329
 
330
+
336
331
  /* Stand-alone Functions */
337
332
  function all_form_names(page) {
338
333
  var names = [];
@@ -356,4 +351,11 @@
356
351
 
357
352
  return text_value;
358
353
  }
354
+
355
+ // return value of first property found: e.g., prop_value(element, 'name', 'id')
356
+ function prop_value() {
357
+ var args = prop_value.arguments;
358
+ var obj = args[0];
359
+ for(i=1; i < args.length; i++) { if (obj[args[i]]) return obj[args[i]]}
360
+ }
359
361
 
data/lib/honey_do.rb CHANGED
@@ -27,7 +27,7 @@ module HoneyDo
27
27
  # ====HTML +form+ element identifiers
28
28
  # <b><tt>name</tt> attribute</b>:: YES
29
29
  # <b><tt>form.elements</tt> index</b>:: YES
30
- # <b><tt>id</tt> attribute</b>:: NO
30
+ # <b><tt>id</tt> attribute</b>:: YES
31
31
  # <b><tt>value</tt> attribute</b>:: NO
32
32
  #
33
33
  # <b>element names (or indexes) without values get <i>clicked </i></b> if they are
@@ -74,6 +74,7 @@ module HoneyDo
74
74
  # <b>These aren't usually necessary</b>.
75
75
  # <tt>:form_name_or_index</tt>:: Defaults to 0, because there is usually just one form per page. +String+ or +Integer+
76
76
  # <tt>:ok_if_not_found</tt>:: +true+ to swallow the error, +nil+/+false+/+null+ if not present (the default). Useful for testing multiple versions of your app when names have changed, or widgets have been added or removed.
77
+ # <tt>:select_as_text</tt>:: +true+ to force droplist values to be treated as text, even if they are digits +nil+/+false+/+null+ if not present (the default). Useful when the visible option text is a number (e.g., "day of month" lists). Without it, the input is taken to an index.
77
78
  # <tt>:one_field_at_a_time</tt>:: +true+ to use mulitple-call mode. Makes Ruby loop on the list, instead JavaScript, forcing a separate <tt>get_eval</tt> call for each item. Effectively slows it down as a means of handling _Ajax_ refreshes in _Firefox_.
78
79
  # <tt>:retry_max</tt>:: 0 or 1 to *_not_* retry at all. Anything > 2 (the default, which means 1 try and 1 retry) is probably useless, but I don't know your app. +Integer+
79
80
  # <tt>:retry_interval</tt>:: To change the default wait time (0.75 seconds) between retries. +Float+
@@ -88,7 +89,7 @@ module HoneyDo
88
89
  retry_interval = processing_params[:retry_interval] ? processing_params[:retry_interval] : 0.75
89
90
 
90
91
  js_open = "dom=new Form_( this, '#{which_form}' )."
91
- js_close = ", '#{processing_params[:ok_if_not_found]}' )"
92
+ js_close = ", '#{processing_params[:ok_if_not_found]}', '#{processing_params[:select_as_text]}' )"
92
93
  errors = ""
93
94
 
94
95
  # when input is a single symbol or int
@@ -178,6 +178,39 @@ class TestGeneralInputOptions < Test::Unit::TestCase
178
178
  assert_nil(browser.get_form_values[:event_reports_area], "no longer firing events")
179
179
  end
180
180
 
181
+ def test_id_works_for_input_if_no_name_present
182
+ input_string = "boy look at the size of that"
183
+ assert_nothing_raised(RuntimeError, "id attribute should be sufficient identifier for HTMLElementCollection") do
184
+ browser.set_form_values(:id_not_name => input_string)
185
+ end
186
+
187
+ assert_equal(input_string, browser.get_form_values[:id_not_name])
188
+ end
189
+
190
+ def test_id_or_name_equivalent_for_input_on_field_with_both
191
+ id_text = "id text"
192
+ name_text = "name is used here"
193
+ assert_nothing_raised(RuntimeError, "id attribute is ok even when there's a name") do
194
+ browser.set_form_values(:id_of_username_field => id_text)
195
+ end
196
+
197
+ assert_equal(id_text, browser.get_form_values[:username])
198
+
199
+ browser.set_form_values(:username => name_text)
200
+
201
+ assert_equal(name_text, browser.get_form_values[:username])
202
+ end
203
+
204
+ def test_name_attribute_trumps_id_attribute
205
+ input_text = "That song with an apostrophe in it by Spirit"
206
+ browser.set_form_values(:id_of_username_field => input_text, :id_not_name => input_text)
207
+
208
+ values_read_back = browser.get_form_values
209
+ assert_equal(input_text, values_read_back[:username], "name attribute trumps id attribute")
210
+ assert_equal(input_text, values_read_back[:id_not_name], "id works because name is not present")
211
+ assert_nil(values_read_back[:id_of_username_field], "id doesn't work because name is present")
212
+ end
213
+
181
214
  protected
182
215
 
183
216
  def setup
@@ -0,0 +1,28 @@
1
+ require 'test_master'
2
+
3
+ class TestSelectFeatures < Test::Unit::TestCase
4
+
5
+ def test_select_digit_label_as_text
6
+ browser.open("day_list.html")
7
+
8
+ browser.set_form_values(:day_of_month => 11 )
9
+ assert_equal("12", browser.get_form_values[:day_of_month], "option selected by index")
10
+
11
+ reset
12
+ browser.set_form_values({:day_of_month => 11}, :select_as_text => true )
13
+ assert_equal("11", browser.get_form_values[:day_of_month], "option selected by option value")
14
+
15
+ reset
16
+ browser.set_form_values({:day_of_month => :last})
17
+ assert_equal("31", browser.get_form_values[:day_of_month], "last option selected, safely by index")
18
+
19
+ reset
20
+ browser.set_form_values({:day_of_month => 31}, :select_as_text => true )
21
+ assert_equal("31", browser.get_form_values[:day_of_month], "option selected by index")
22
+
23
+ reset
24
+ assert_raise(RuntimeError, "index out of bounds: 'e.options[i] has no properties'") do
25
+ browser.set_form_values({:day_of_month => 31}, :retry_max => 0 )
26
+ end
27
+ end
28
+ end
@@ -29,7 +29,7 @@ class TestSelectFeatures < Test::Unit::TestCase
29
29
  reset_then_set(:color => option_value_property.upcase)
30
30
  assert_equal(option_text_property, browser.get_form_values[:color], "case insensitive")
31
31
  end
32
-
32
+
33
33
  # substring match - anchored to ^ (beginning of string); *, ? and + are just text (not wildcards)
34
34
  def test_select_from_droplist_by_substring_match_on_visible_text
35
35
  default_selection = browser.get_form_values[:color]
@@ -152,4 +152,5 @@ class TestSelectFeatures < Test::Unit::TestCase
152
152
  def reset_then_set_without_retry(input_hash)
153
153
  browser.set_form_values(input_hash.to_a.unshift(:resetButton), :retry_max => 0 )
154
154
  end
155
+
155
156
  end
data/test/submit_test.rb CHANGED
@@ -54,6 +54,12 @@ class TestSubmitForm < Test::Unit::TestCase
54
54
  verify_all_values_persist_on_display_page(submitted_values)
55
55
  end
56
56
 
57
+ def test_fields_with_no_name_not_submitted
58
+ browser.set_form_values([[:id_not_name, "snooky!"], :submitButton])
59
+ verify_page_loaded
60
+ assert_nil( browser.get_cell_ids_and_text[:id_not_name])
61
+ end
62
+
57
63
  protected
58
64
 
59
65
  def setup
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honey-do
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Camper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-26 00:00:00 -06:00
12
+ date: 2008-12-18 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,7 @@ extra_rdoc_files:
41
41
  - test/general_form_test.rb
42
42
  - test/hidden_and_disabled_field_test.rb
43
43
  - test/radio_button_test.rb
44
+ - test/select_as_text_test.rb
44
45
  - test/select_list_test.rb
45
46
  - test/submit_test.rb
46
47
  - test/test_master.rb
@@ -61,6 +62,7 @@ files:
61
62
  - test/general_form_test.rb
62
63
  - test/hidden_and_disabled_field_test.rb
63
64
  - test/radio_button_test.rb
65
+ - test/select_as_text_test.rb
64
66
  - test/select_list_test.rb
65
67
  - test/submit_test.rb
66
68
  - test/test_master.rb
@@ -68,10 +70,13 @@ files:
68
70
  - demo/display
69
71
  - demo/display/webrick_servlet_needs_this_folder.txt
70
72
  - demo/page
73
+ - demo/page/day_list.html
71
74
  - demo/page/everything.html
72
75
  - demo/page/everything.js
73
76
  - demo/webrick-servlet.rb
74
77
  - functional_testcase/functional_testcase.rb
78
+ - bin/init_selenium_proxy.bat
79
+ - bin/killableprocess.exe
75
80
  - bin/start_selenium_proxy.bat
76
81
  - bin/start_selenium_proxy.sh
77
82
  - js/user-extensions.js