honey-do 0.5.0 → 0.6.0

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