hatemile 2.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/Rakefile +64 -0
  6. data/hatemile.gemspec +37 -0
  7. data/lib/hatemile/accessible_association.rb +62 -0
  8. data/lib/hatemile/accessible_css.rb +43 -0
  9. data/lib/hatemile/accessible_display.rb +178 -0
  10. data/lib/hatemile/accessible_event.rb +95 -0
  11. data/lib/hatemile/accessible_form.rb +101 -0
  12. data/lib/hatemile/accessible_navigation.rb +82 -0
  13. data/lib/hatemile/helper.rb +58 -0
  14. data/lib/hatemile/implementation/accessible_association_implementation.rb +346 -0
  15. data/lib/hatemile/implementation/accessible_css_implementation.rb +772 -0
  16. data/lib/hatemile/implementation/accessible_display_implementation.rb +1362 -0
  17. data/lib/hatemile/implementation/accessible_event_implementation.rb +278 -0
  18. data/lib/hatemile/implementation/accessible_form_implementation.rb +386 -0
  19. data/lib/hatemile/implementation/accessible_navigation_implementation.rb +561 -0
  20. data/lib/hatemile/util/common_functions.rb +106 -0
  21. data/lib/hatemile/util/configure.rb +92 -0
  22. data/lib/hatemile/util/css/rcp/rcp_declaration.rb +77 -0
  23. data/lib/hatemile/util/css/rcp/rcp_parser.rb +115 -0
  24. data/lib/hatemile/util/css/rcp/rcp_rule.rb +86 -0
  25. data/lib/hatemile/util/css/style_sheet_declaration.rb +59 -0
  26. data/lib/hatemile/util/css/style_sheet_parser.rb +43 -0
  27. data/lib/hatemile/util/css/style_sheet_rule.rb +73 -0
  28. data/lib/hatemile/util/html/html_dom_element.rb +234 -0
  29. data/lib/hatemile/util/html/html_dom_node.rb +131 -0
  30. data/lib/hatemile/util/html/html_dom_parser.rb +150 -0
  31. data/lib/hatemile/util/html/html_dom_text_node.rb +43 -0
  32. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_element.rb +302 -0
  33. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_node.rb +112 -0
  34. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_parser.rb +208 -0
  35. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_text_node.rb +83 -0
  36. data/lib/hatemile/util/id_generator.rb +53 -0
  37. data/lib/js/common.js +98 -0
  38. data/lib/js/eventlistener.js +36 -0
  39. data/lib/js/include.js +292 -0
  40. data/lib/js/scriptlist_validation_fields.js +13 -0
  41. data/lib/js/validation.js +205 -0
  42. data/lib/locale/en-US.yml +388 -0
  43. data/lib/locale/pt-BR.yml +389 -0
  44. data/lib/skippers.xml +6 -0
  45. data/lib/symbols.xml +40 -0
  46. data/test/locale/en-US.yml +5 -0
  47. data/test/locale/pt-BR.yml +4 -0
  48. data/test/test_accessible_association_implementation.rb +258 -0
  49. data/test/test_accessible_css_implementation.rb +518 -0
  50. data/test/test_accessible_display_implementation.rb +873 -0
  51. data/test/test_accessible_form_implementation.rb +283 -0
  52. data/test/test_accessible_navigation_implementation.rb +228 -0
  53. data/test/test_common_functions.rb +128 -0
  54. data/test/test_configure.rb +73 -0
  55. data/test/test_nokogiri_html_dom_element.rb +586 -0
  56. data/test/test_nokogiri_html_dom_parser.rb +363 -0
  57. data/test/test_nokogiri_html_dom_text_node.rb +225 -0
  58. data/test/test_rcp_declaration.rb +103 -0
  59. data/test/test_rcp_parser.rb +86 -0
  60. data/test/test_rcp_rule.rb +89 -0
  61. metadata +199 -0
@@ -0,0 +1,283 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+ require 'test/unit'
16
+ require 'test/unit/assertions'
17
+
18
+ require File.join(
19
+ File.dirname(File.dirname(__FILE__)),
20
+ 'lib',
21
+ 'hatemile',
22
+ 'implementation',
23
+ 'accessible_form_implementation'
24
+ )
25
+ require File.join(
26
+ File.dirname(File.dirname(__FILE__)),
27
+ 'lib',
28
+ 'hatemile',
29
+ 'util',
30
+ 'html',
31
+ 'nokogiri',
32
+ 'nokogiri_html_dom_parser'
33
+ )
34
+
35
+ ##
36
+ # Test methods of Hatemile::Implementation::AccessibleFormImplementation class.
37
+ class TestAccessibleFormImplementation < Test::Unit::TestCase
38
+ ##
39
+ # The name of attribute for not modify the elements.
40
+ DATA_IGNORE = 'data-ignoreaccessibilityfix="true"'.freeze
41
+
42
+ ##
43
+ # Test mark_all_required_fields method.
44
+ def test_mark_all_required_fields
45
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
46
+ <!DOCTYPE html>
47
+ <html>
48
+ <head>
49
+ <title>HaTeMiLe Tests</title>
50
+ <meta charset=\"UTF-8\" />
51
+ </head>
52
+ <body>
53
+ <label for=\"field1\">Field1</label>
54
+ <input type=\"text\" id=\"field1\" required />
55
+ <label for=\"field2\">Field2</label>
56
+ <input type=\"text\" id=\"field2\" required #{DATA_IGNORE} />
57
+ <label for=\"field3\">Field3</label>
58
+ <input type=\"text\" id=\"field3\" />
59
+ </body>
60
+ </html>
61
+ ")
62
+ accessibleform =
63
+ Hatemile::Implementation::AccessibleFormImplementation.new(html_parser)
64
+ accessibleform.mark_all_required_fields
65
+ field1 = html_parser.find('#field1').first_result
66
+ field2 = html_parser.find('#field2').first_result
67
+ field3 = html_parser.find('#field3').first_result
68
+
69
+ assert_equal('true', field1.get_attribute('aria-required'))
70
+ assert(!field2.has_attribute?('aria-required'))
71
+ assert(!field3.has_attribute?('aria-required'))
72
+ end
73
+
74
+ ##
75
+ # Test mark_all_range_fields method.
76
+ def test_mark_all_range_fields
77
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
78
+ <!DOCTYPE html>
79
+ <html>
80
+ <head>
81
+ <title>HaTeMiLe Tests</title>
82
+ <meta charset=\"UTF-8\" />
83
+ </head>
84
+ <body>
85
+ <label for=\"field1\">Field1</label>
86
+ <input type=\"number\" min=\"0\" id=\"field1\" />
87
+ <label for=\"field2\">Field2</label>
88
+ <input type=\"range\" max=\"10\" id=\"field2\" />
89
+ <label for=\"field3\">Field3</label>
90
+ <input type=\"number\" min=\"1\" max=\"9\" id=\"field3\" />
91
+ <label for=\"field4\">Field4</label>
92
+ <input type=\"number\" id=\"field4\" />
93
+ <label for=\"field5\">Field5</label>
94
+ <input type=\"number\" min=\"0\" id=\"field5\" #{DATA_IGNORE} />
95
+ <label for=\"field6\">Field6</label>
96
+ <input type=\"number\" max=\"11\" id=\"field6\" #{DATA_IGNORE} />
97
+ </body>
98
+ </html>
99
+ ")
100
+ accessibleform =
101
+ Hatemile::Implementation::AccessibleFormImplementation.new(html_parser)
102
+ accessibleform.mark_all_range_fields
103
+ field1 = html_parser.find('#field1').first_result
104
+ field2 = html_parser.find('#field2').first_result
105
+ field3 = html_parser.find('#field3').first_result
106
+ field4 = html_parser.find('#field4').first_result
107
+ field5 = html_parser.find('#field5').first_result
108
+ field6 = html_parser.find('#field6').first_result
109
+
110
+ assert_equal('0', field1.get_attribute('aria-valuemin'))
111
+ assert_equal('10', field2.get_attribute('aria-valuemax'))
112
+ assert_equal('1', field3.get_attribute('aria-valuemin'))
113
+ assert_equal('9', field3.get_attribute('aria-valuemax'))
114
+ assert(!field4.has_attribute?('aria-valuemin'))
115
+ assert(!field4.has_attribute?('aria-valuemax'))
116
+ assert(!field5.has_attribute?('aria-valuemin'))
117
+ assert(!field6.has_attribute?('aria-valuemax'))
118
+ end
119
+
120
+ ##
121
+ # Test mark_all_autocomplete_fields method.
122
+ def test_mark_all_autocomplete_fields
123
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
124
+ <!DOCTYPE html>
125
+ <html>
126
+ <head>
127
+ <title>HaTeMiLe Tests</title>
128
+ <meta charset=\"UTF-8\" />
129
+ </head>
130
+ <body>
131
+ <!-- Autocomplete ON -->
132
+ <label for=\"field1\">Field1</label>
133
+ <input type=\"text\" id=\"field1\" autocomplete=\"on\" />
134
+ <label for=\"field2\">Field2</label>
135
+ <textarea id=\"field2\" autocomplete=\"on\"></textarea>
136
+ <label for=\"field3\">Field3</label>
137
+ <input type=\"text\" id=\"field3\" list=\"datalist1\" />
138
+ <datalist id=\"datalist1\">
139
+ <option value=\"Value1\" />
140
+ <option value=\"Value2\" />
141
+ <option value=\"Value3\" />
142
+ <option value=\"Value4\" />
143
+ </datalist>
144
+ <form autocomplete=\"on\" id=\"form1\">
145
+ <label for=\"field4\">Field4</label>
146
+ <input type=\"text\" id=\"field4\" />
147
+ <label for=\"field5\">Field5</label>
148
+ <textarea id=\"field5\"></textarea>
149
+ <label for=\"field6\">Field6</label>
150
+ <input type=\"text\" id=\"field6\" autocomplete=\"off\" />
151
+ <label for=\"field7\">Field7</label>
152
+ <textarea id=\"field7\" autocomplete=\"off\"></textarea>
153
+ </form>
154
+ <label for=\"field8\">Field8</label>
155
+ <input type=\"text\" id=\"field8\" form=\"form1\" />
156
+ <label for=\"field9\">Field9</label>
157
+ <input id=\"field9\" form=\"form1\" autocomplete=\"off\" />
158
+
159
+ <!-- Autocomplete OFF -->
160
+ <label for=\"field10\">Field10</label>
161
+ <input type=\"text\" id=\"field10\" autocomplete=\"off\" />
162
+ <label for=\"field11\">Field11</label>
163
+ <textarea id=\"field11\" autocomplete=\"off\"></textarea>
164
+ <form autocomplete=\"off\" id=\"form2\">
165
+ <label for=\"field12\">Field12</label>
166
+ <input type=\"text\" id=\"field12\" />
167
+ <label for=\"field13\">Field13</label>
168
+ <textarea id=\"field13\"></textarea>
169
+ <label for=\"field14\">Field14</label>
170
+ <input type=\"text\" id=\"field14\" autocomplete=\"on\" />
171
+ <label for=\"field15\">Field15</label>
172
+ <textarea id=\"field15\" autocomplete=\"on\"></textarea>
173
+ <label for=\"field16\">Field16</label>
174
+ <input type=\"text\" id=\"field16\" list=\"datalist2\" />
175
+ <datalist id=\"datalist2\">
176
+ <option value=\"Value1\" />
177
+ <option value=\"Value2\" />
178
+ <option value=\"Value3\" />
179
+ <option value=\"Value4\" />
180
+ </datalist>
181
+ </form>
182
+ <label for=\"field17\">Field17</label>
183
+ <input type=\"text\" id=\"field17\" form=\"form2\" />
184
+ <label for=\"field18\">Field18</label>
185
+ <input id=\"field18\" form=\"form2\" autocomplete=\"on\" />
186
+
187
+ <!-- Ignore -->
188
+ <label for=\"field19\">Field19</label>
189
+ <input id=\"field19\" autocomplete=\"on\" #{DATA_IGNORE} />
190
+ <label for=\"field20\">Field20</label>
191
+ <textarea id=\"field20\" autocomplete=\"on\" #{DATA_IGNORE}>
192
+ </textarea>
193
+ <label for=\"field21\">Field21</label>
194
+ <input id=\"field21\" list=\"datalist3\" #{DATA_IGNORE} />
195
+ <datalist id=\"datalist3\">
196
+ <option value=\"Value1\" />
197
+ <option value=\"Value2\" />
198
+ <option value=\"Value3\" />
199
+ <option value=\"Value4\" />
200
+ </datalist>
201
+ <form autocomplete=\"on\" id=\"form3\" #{DATA_IGNORE}>
202
+ <label for=\"field22\">Field22</label>
203
+ <input type=\"text\" id=\"field22\" />
204
+ <label for=\"field23\">Field23</label>
205
+ <textarea id=\"field23\"></textarea>
206
+ <label for=\"field24\">Field24</label>
207
+ <input type=\"text\" id=\"field24\" autocomplete=\"off\" />
208
+ <label for=\"field25\">Field25</label>
209
+ <textarea id=\"field25\" autocomplete=\"off\"></textarea>
210
+ </form>
211
+ <label for=\"field26\">Field26</label>
212
+ <input type=\"text\" id=\"field26\" form=\"form3\" />
213
+ <label for=\"field27\">Field27</label>
214
+ <input id=\"field27\" form=\"form3\" autocomplete=\"off\" />
215
+ <label for=\"field28\">Field28</label>
216
+ <input id=\"field28\" form=\"form3\" #{DATA_IGNORE} />
217
+ </body>
218
+ </html>
219
+ ")
220
+ accessibleform =
221
+ Hatemile::Implementation::AccessibleFormImplementation.new(html_parser)
222
+ accessibleform.mark_all_autocomplete_fields
223
+ field1 = html_parser.find('#field1').first_result
224
+ field2 = html_parser.find('#field2').first_result
225
+ field3 = html_parser.find('#field3').first_result
226
+ field4 = html_parser.find('#field4').first_result
227
+ field5 = html_parser.find('#field5').first_result
228
+ field6 = html_parser.find('#field6').first_result
229
+ field7 = html_parser.find('#field7').first_result
230
+ field8 = html_parser.find('#field8').first_result
231
+ field9 = html_parser.find('#field9').first_result
232
+ field10 = html_parser.find('#field10').first_result
233
+ field11 = html_parser.find('#field11').first_result
234
+ field12 = html_parser.find('#field12').first_result
235
+ field13 = html_parser.find('#field13').first_result
236
+ field14 = html_parser.find('#field14').first_result
237
+ field15 = html_parser.find('#field15').first_result
238
+ field16 = html_parser.find('#field16').first_result
239
+ field17 = html_parser.find('#field17').first_result
240
+ field18 = html_parser.find('#field18').first_result
241
+ field19 = html_parser.find('#field19').first_result
242
+ field20 = html_parser.find('#field20').first_result
243
+ field21 = html_parser.find('#field21').first_result
244
+ field22 = html_parser.find('#field22').first_result
245
+ field23 = html_parser.find('#field23').first_result
246
+ field24 = html_parser.find('#field24').first_result
247
+ field25 = html_parser.find('#field25').first_result
248
+ field26 = html_parser.find('#field26').first_result
249
+ field27 = html_parser.find('#field27').first_result
250
+ field28 = html_parser.find('#field28').first_result
251
+
252
+ assert_equal('both', field1.get_attribute('aria-autocomplete'))
253
+ assert_equal('both', field2.get_attribute('aria-autocomplete'))
254
+ assert_equal('list', field3.get_attribute('aria-autocomplete'))
255
+ assert_equal('both', field4.get_attribute('aria-autocomplete'))
256
+ assert_equal('both', field5.get_attribute('aria-autocomplete'))
257
+ assert_equal('none', field6.get_attribute('aria-autocomplete'))
258
+ assert_equal('none', field7.get_attribute('aria-autocomplete'))
259
+ assert_equal('both', field8.get_attribute('aria-autocomplete'))
260
+ assert_equal('none', field9.get_attribute('aria-autocomplete'))
261
+
262
+ assert_equal('none', field10.get_attribute('aria-autocomplete'))
263
+ assert_equal('none', field11.get_attribute('aria-autocomplete'))
264
+ assert_equal('none', field12.get_attribute('aria-autocomplete'))
265
+ assert_equal('none', field13.get_attribute('aria-autocomplete'))
266
+ assert_equal('both', field14.get_attribute('aria-autocomplete'))
267
+ assert_equal('both', field15.get_attribute('aria-autocomplete'))
268
+ assert_equal('list', field16.get_attribute('aria-autocomplete'))
269
+ assert_equal('none', field17.get_attribute('aria-autocomplete'))
270
+ assert_equal('both', field18.get_attribute('aria-autocomplete'))
271
+
272
+ assert(!field19.has_attribute?('aria-autocomplete'))
273
+ assert(!field20.has_attribute?('aria-autocomplete'))
274
+ assert(!field21.has_attribute?('aria-autocomplete'))
275
+ assert(!field22.has_attribute?('aria-autocomplete'))
276
+ assert(!field23.has_attribute?('aria-autocomplete'))
277
+ assert(!field24.has_attribute?('aria-autocomplete'))
278
+ assert(!field25.has_attribute?('aria-autocomplete'))
279
+ assert('both', field26.get_attribute('aria-autocomplete'))
280
+ assert('none', field27.get_attribute('aria-autocomplete'))
281
+ assert(!field28.has_attribute?('aria-autocomplete'))
282
+ end
283
+ end
@@ -0,0 +1,228 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+ require 'test/unit'
16
+ require 'test/unit/assertions'
17
+
18
+ require File.join(
19
+ File.dirname(File.dirname(__FILE__)),
20
+ 'lib',
21
+ 'hatemile',
22
+ 'implementation',
23
+ 'accessible_navigation_implementation'
24
+ )
25
+ require File.join(
26
+ File.dirname(File.dirname(__FILE__)),
27
+ 'lib',
28
+ 'hatemile',
29
+ 'util',
30
+ 'configure'
31
+ )
32
+ require File.join(
33
+ File.dirname(File.dirname(__FILE__)),
34
+ 'lib',
35
+ 'hatemile',
36
+ 'util',
37
+ 'html',
38
+ 'nokogiri',
39
+ 'nokogiri_html_dom_parser'
40
+ )
41
+
42
+ ##
43
+ # Test methods of Hatemile::Implementation::AccessibleNavigationImplementation
44
+ # class.
45
+ class TestAccessibleNavigationImplementation < Test::Unit::TestCase
46
+ ##
47
+ # The name of attribute for not modify the elements.
48
+ DATA_IGNORE = 'data-ignoreaccessibilityfix="true"'.freeze
49
+
50
+ ##
51
+ # The configuration of HaTeMiLe.
52
+ CONFIGURE = Hatemile::Util::Configure.new.freeze
53
+
54
+ ##
55
+ # Test provide_navigation_by_all_skippers method.
56
+ def test_provide_navigation_by_all_skippers
57
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
58
+ <!DOCTYPE html>
59
+ <html>
60
+ <head>
61
+ <title>HaTeMiLe Tests</title>
62
+ <meta charset=\"UTF-8\" />
63
+ </head>
64
+ <body>
65
+ <main>Main content</main>
66
+ <div id=\"container-shortcuts-after\">Container of shortcuts</div>
67
+ <div id=\"container-heading-after\" #{DATA_IGNORE}>
68
+ Container of headings
69
+ </div>
70
+ </body>
71
+ </html>
72
+ ")
73
+ navigation =
74
+ Hatemile::Implementation::AccessibleNavigationImplementation.new(
75
+ html_parser,
76
+ CONFIGURE
77
+ )
78
+ navigation.provide_navigation_by_all_skippers
79
+ body_children = html_parser.find('body').first_result.get_children_elements
80
+ main_element = html_parser.find('main').first_result
81
+ main_id = main_element.get_attribute('id')
82
+ main_anchor = html_parser.find(
83
+ "[data-anchorfor=\"#{main_id}\"]"
84
+ ).first_result
85
+ main_link = html_parser.find(
86
+ "#container-skippers a[href=\"##{main_anchor.get_attribute('id')}\"]"
87
+ ).first_result
88
+ container_shortcuts = html_parser.find(
89
+ '#container-shortcuts-after'
90
+ ).first_result
91
+ container_shortcuts_anchor = html_parser.find(
92
+ '[data-anchorfor="container-shortcuts-after"]'
93
+ ).first_result
94
+ container_shortcuts_id = container_shortcuts_anchor.get_attribute('id')
95
+ container_shortcuts_link = html_parser.find(
96
+ "#container-skippers a[href=\"##{container_shortcuts_id}\"]"
97
+ ).first_result
98
+ container_heading_anchor = html_parser.find(
99
+ '[data-anchorfor="container-heading-after"]'
100
+ ).first_result
101
+
102
+ assert_not_nil(html_parser.find('#container-skippers').first_result)
103
+ assert_not_nil(main_anchor)
104
+ assert_not_nil(container_shortcuts_anchor)
105
+ assert_nil(container_heading_anchor)
106
+ assert_not_nil(main_link)
107
+ assert_not_nil(container_shortcuts_link)
108
+ assert_equal(
109
+ body_children.index(main_element),
110
+ body_children.index(main_anchor) + 1
111
+ )
112
+ assert_equal(
113
+ body_children.index(container_shortcuts),
114
+ body_children.index(container_shortcuts_anchor) + 1
115
+ )
116
+ end
117
+
118
+ ##
119
+ # Test provide_navigation_by_all_headings method.
120
+ def test_provide_navigation_by_all_headings
121
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
122
+ <!DOCTYPE html>
123
+ <html>
124
+ <head>
125
+ <title>HaTeMiLe Tests</title>
126
+ <meta charset=\"UTF-8\" />
127
+ </head>
128
+ <body>
129
+ <div>
130
+ <h1><span>Heading 1</span></h1>
131
+ <h2><span>Heading 1.2.1</span></h2>
132
+ <div>
133
+ <span></span>
134
+ <div><h2><span>Heading 1.2.2</span></h2></div>
135
+ <span></span>
136
+ </div>
137
+ <h3><span>Heading 1.2.2.3.1</span></h3>
138
+ <h4><span>Heading 1.2.2.3.1.4.1</span></h4>
139
+ <h2><span>Heading 1.2.3</span></h2>
140
+ <h3><span>Heading 1.2.3.3.1</span></h3>
141
+ </div>
142
+ </body>
143
+ </html>
144
+ ")
145
+ navigation =
146
+ Hatemile::Implementation::AccessibleNavigationImplementation.new(
147
+ html_parser,
148
+ CONFIGURE
149
+ )
150
+ navigation.provide_navigation_by_all_headings
151
+ container = html_parser.find('#container-heading-after').first_result
152
+ headings = html_parser.find('h1, h2, h3, h4').list_results
153
+ container_list = html_parser.find(container).find_descendants(
154
+ '[data-headinglevel]'
155
+ ).list_results
156
+ links = html_parser.find('[data-headinglevel] a').list_results
157
+
158
+ assert_not_nil(container)
159
+ assert_equal(
160
+ 1,
161
+ container_list.first.get_attribute('data-headinglevel').to_i
162
+ )
163
+ assert_equal(2, container_list[1].get_attribute('data-headinglevel').to_i)
164
+ assert_equal(2, container_list[2].get_attribute('data-headinglevel').to_i)
165
+ assert_equal(3, container_list[3].get_attribute('data-headinglevel').to_i)
166
+ assert_equal(4, container_list[4].get_attribute('data-headinglevel').to_i)
167
+ assert_equal(2, container_list[5].get_attribute('data-headinglevel').to_i)
168
+ assert_equal(3, container_list[6].get_attribute('data-headinglevel').to_i)
169
+ links.each do |link|
170
+ anchor = html_parser.find(link.get_attribute('href')).first_result
171
+ heading = html_parser.find(
172
+ '#' + anchor.get_attribute('data-headinganchorfor')
173
+ ).first_result
174
+ children_elements = anchor.get_parent_element.get_children_elements
175
+
176
+ assert_not_nil(anchor)
177
+ assert(headings.include?(heading))
178
+ assert_equal(
179
+ children_elements.index(anchor),
180
+ children_elements.index(heading) - 1
181
+ )
182
+ end
183
+ end
184
+
185
+ ##
186
+ # Test provide_navigation_to_all_long_descriptions method.
187
+ def test_provide_navigation_to_all_long_descriptions
188
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new("
189
+ <!DOCTYPE html>
190
+ <html>
191
+ <head>
192
+ <title>HaTeMiLe Tests</title>
193
+ <meta charset=\"UTF-8\" />
194
+ </head>
195
+ <body>
196
+ <img src=\"i1.jpg\" alt=\"I1\" />
197
+ <img src=\"i2.jpg\" alt=\"I2\" longdesc=\"i2.html\" />
198
+ <img src=\"i3.jpg\" alt=\"\" longdesc=\"i3.html\" />
199
+ <img src=\"i4.jpg\" longdesc=\"i4.html\" />
200
+ <img src=\"i5.jpg\" alt=\"I5\" longdesc=\"i5.html\" #{DATA_IGNORE} />
201
+ </body>
202
+ </html>
203
+ ")
204
+ navigation =
205
+ Hatemile::Implementation::AccessibleNavigationImplementation.new(
206
+ html_parser,
207
+ CONFIGURE
208
+ )
209
+ navigation.provide_navigation_to_all_long_descriptions
210
+ long_description_links = html_parser.find(
211
+ '[data-attributelongdescriptionof]'
212
+ ).list_results
213
+ image2_link = long_description_links.first
214
+ image2 = html_parser.find(
215
+ '#' + image2_link.get_attribute('data-attributelongdescriptionof')
216
+ ).first_result
217
+ image3_link = long_description_links.last
218
+ image3 = html_parser.find(
219
+ '#' + image3_link.get_attribute('data-attributelongdescriptionof')
220
+ ).first_result
221
+
222
+ assert_equal(2, long_description_links.length)
223
+ assert_equal('i2.jpg', image2.get_attribute('src'))
224
+ assert_equal('i3.jpg', image3.get_attribute('src'))
225
+ assert_equal(' (Long description of I2)', image2_link.get_text_content)
226
+ assert_equal(' (Long description of )', image3_link.get_text_content)
227
+ end
228
+ end