watir 7.2.0 → 7.2.1

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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/chrome.yml +1 -1
  3. data/.github/workflows/edge.yml +1 -1
  4. data/.github/workflows/firefox.yml +1 -1
  5. data/.github/workflows/ie.yml +1 -1
  6. data/.github/workflows/safari.yml +1 -1
  7. data/.github/workflows/unit.yml +1 -1
  8. data/.rubocop.yml +25 -12
  9. data/.rubocop_todo.yml +8 -1
  10. data/CHANGES.md +6 -1
  11. data/LICENSE +2 -2
  12. data/lib/watir/capabilities.rb +1 -1
  13. data/lib/watir/locators/anchor/selector_builder.rb +3 -0
  14. data/lib/watir/locators/element/matcher.rb +2 -1
  15. data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -1
  16. data/lib/watir/locators/text_field/matcher.rb +0 -4
  17. data/lib/watir/version.rb +1 -1
  18. data/spec/locator_spec_helper.rb +0 -8
  19. data/spec/unit/capabilities_spec.rb +553 -561
  20. data/spec/unit/element_locator_spec.rb +89 -78
  21. data/spec/unit/match_elements/button_spec.rb +69 -62
  22. data/spec/unit/match_elements/element_spec.rb +303 -309
  23. data/spec/unit/match_elements/text_field_spec.rb +76 -73
  24. data/spec/unit/selector_builder/anchor_spec.rb +39 -33
  25. data/spec/unit/selector_builder/button_spec.rb +209 -202
  26. data/spec/unit/selector_builder/cell_spec.rb +48 -42
  27. data/spec/unit/selector_builder/element_spec.rb +634 -627
  28. data/spec/unit/selector_builder/row_spec.rb +119 -113
  29. data/spec/unit/selector_builder/text_field_spec.rb +195 -188
  30. data/spec/unit/selector_builder/textarea_spec.rb +22 -14
  31. data/spec/unit/wait_spec.rb +85 -81
  32. data/spec/watirspec/adjacent_spec.rb +249 -247
  33. data/spec/watirspec/after_hooks_spec.rb +161 -159
  34. data/spec/watirspec/alert_spec.rb +61 -58
  35. data/spec/watirspec/browser_spec.rb +409 -409
  36. data/spec/watirspec/capabilities_spec.rb +89 -99
  37. data/spec/watirspec/cookies_spec.rb +120 -118
  38. data/spec/watirspec/drag_and_drop_spec.rb +26 -24
  39. data/spec/watirspec/element_hidden_spec.rb +66 -60
  40. data/spec/watirspec/elements/area_spec.rb +49 -47
  41. data/spec/watirspec/elements/areas_spec.rb +27 -25
  42. data/spec/watirspec/elements/button_spec.rb +253 -251
  43. data/spec/watirspec/elements/buttons_spec.rb +36 -34
  44. data/spec/watirspec/elements/checkbox_spec.rb +48 -36
  45. data/spec/watirspec/elements/checkboxes_spec.rb +29 -27
  46. data/spec/watirspec/elements/collections_spec.rb +126 -119
  47. data/spec/watirspec/elements/date_field_spec.rb +185 -183
  48. data/spec/watirspec/elements/date_fields_spec.rb +29 -27
  49. data/spec/watirspec/elements/date_time_field_spec.rb +197 -195
  50. data/spec/watirspec/elements/date_time_fields_spec.rb +30 -28
  51. data/spec/watirspec/elements/dd_spec.rb +87 -85
  52. data/spec/watirspec/elements/dds_spec.rb +27 -25
  53. data/spec/watirspec/elements/del_spec.rb +106 -104
  54. data/spec/watirspec/elements/dels_spec.rb +26 -24
  55. data/spec/watirspec/elements/div_spec.rb +225 -221
  56. data/spec/watirspec/elements/divs_spec.rb +37 -35
  57. data/spec/watirspec/elements/dl_spec.rb +110 -108
  58. data/spec/watirspec/elements/dls_spec.rb +28 -26
  59. data/spec/watirspec/elements/dt_spec.rb +86 -84
  60. data/spec/watirspec/elements/dts_spec.rb +27 -25
  61. data/spec/watirspec/elements/element_spec.rb +794 -775
  62. data/spec/watirspec/elements/elements_spec.rb +40 -38
  63. data/spec/watirspec/elements/em_spec.rb +62 -60
  64. data/spec/watirspec/elements/ems_spec.rb +28 -26
  65. data/spec/watirspec/elements/filefield_spec.rb +116 -114
  66. data/spec/watirspec/elements/filefields_spec.rb +28 -26
  67. data/spec/watirspec/elements/font_spec.rb +20 -18
  68. data/spec/watirspec/elements/form_spec.rb +51 -49
  69. data/spec/watirspec/elements/forms_spec.rb +29 -27
  70. data/spec/watirspec/elements/frame_spec.rb +89 -87
  71. data/spec/watirspec/elements/frames_spec.rb +27 -25
  72. data/spec/watirspec/elements/hidden_spec.rb +81 -79
  73. data/spec/watirspec/elements/hiddens_spec.rb +28 -26
  74. data/spec/watirspec/elements/hn_spec.rb +59 -57
  75. data/spec/watirspec/elements/hns_spec.rb +26 -24
  76. data/spec/watirspec/elements/iframe_spec.rb +195 -191
  77. data/spec/watirspec/elements/iframes_spec.rb +31 -29
  78. data/spec/watirspec/elements/image_spec.rb +148 -146
  79. data/spec/watirspec/elements/images_spec.rb +26 -24
  80. data/spec/watirspec/elements/input_spec.rb +9 -7
  81. data/spec/watirspec/elements/ins_spec.rb +106 -104
  82. data/spec/watirspec/elements/inses_spec.rb +26 -24
  83. data/spec/watirspec/elements/label_spec.rb +56 -54
  84. data/spec/watirspec/elements/labels_spec.rb +26 -24
  85. data/spec/watirspec/elements/li_spec.rb +76 -74
  86. data/spec/watirspec/elements/link_spec.rb +173 -177
  87. data/spec/watirspec/elements/links_spec.rb +45 -43
  88. data/spec/watirspec/elements/lis_spec.rb +27 -25
  89. data/spec/watirspec/elements/list_spec.rb +44 -42
  90. data/spec/watirspec/elements/map_spec.rb +57 -55
  91. data/spec/watirspec/elements/maps_spec.rb +27 -25
  92. data/spec/watirspec/elements/meta_spec.rb +16 -14
  93. data/spec/watirspec/elements/metas_spec.rb +26 -24
  94. data/spec/watirspec/elements/ol_spec.rb +56 -65
  95. data/spec/watirspec/elements/ols_spec.rb +26 -24
  96. data/spec/watirspec/elements/option_spec.rb +91 -89
  97. data/spec/watirspec/elements/p_spec.rb +81 -79
  98. data/spec/watirspec/elements/pre_spec.rb +77 -75
  99. data/spec/watirspec/elements/pres_spec.rb +26 -24
  100. data/spec/watirspec/elements/ps_spec.rb +26 -24
  101. data/spec/watirspec/elements/radio_spec.rb +251 -249
  102. data/spec/watirspec/elements/radios_spec.rb +28 -26
  103. data/spec/watirspec/elements/select_list_spec.rb +537 -526
  104. data/spec/watirspec/elements/select_lists_spec.rb +32 -30
  105. data/spec/watirspec/elements/span_spec.rb +112 -110
  106. data/spec/watirspec/elements/spans_spec.rb +26 -24
  107. data/spec/watirspec/elements/strong_spec.rb +58 -58
  108. data/spec/watirspec/elements/strongs_spec.rb +28 -26
  109. data/spec/watirspec/elements/table_spec.rb +192 -139
  110. data/spec/watirspec/elements/tables_spec.rb +28 -26
  111. data/spec/watirspec/elements/tbody_spec.rb +74 -72
  112. data/spec/watirspec/elements/tbodys_spec.rb +40 -38
  113. data/spec/watirspec/elements/td_spec.rb +66 -64
  114. data/spec/watirspec/elements/tds_spec.rb +41 -39
  115. data/spec/watirspec/elements/text_field_spec.rb +206 -204
  116. data/spec/watirspec/elements/text_fields_spec.rb +30 -28
  117. data/spec/watirspec/elements/textarea_spec.rb +20 -18
  118. data/spec/watirspec/elements/textareas_spec.rb +18 -16
  119. data/spec/watirspec/elements/tfoot_spec.rb +65 -63
  120. data/spec/watirspec/elements/tfoots_spec.rb +42 -40
  121. data/spec/watirspec/elements/thead_spec.rb +65 -63
  122. data/spec/watirspec/elements/theads_spec.rb +42 -40
  123. data/spec/watirspec/elements/tr_spec.rb +48 -46
  124. data/spec/watirspec/elements/trs_spec.rb +42 -40
  125. data/spec/watirspec/elements/ul_spec.rb +56 -54
  126. data/spec/watirspec/elements/uls_spec.rb +26 -24
  127. data/spec/watirspec/radio_set_spec.rb +269 -267
  128. data/spec/watirspec/screenshot_spec.rb +20 -18
  129. data/spec/watirspec/scroll_spec.rb +152 -148
  130. data/spec/watirspec/shadow_root_spec.rb +86 -83
  131. data/spec/watirspec/user_editable_spec.rb +200 -198
  132. data/spec/watirspec/wait_spec.rb +289 -295
  133. data/spec/watirspec/window_switching_spec.rb +422 -434
  134. data/spec/watirspec_helper.rb +1 -23
  135. data/watir.gemspec +5 -4
  136. metadata +44 -33
  137. data/spec/watirspec/attributes_spec.rb +0 -18
  138. data/spec/watirspec/elements/table_nesting_spec.rb +0 -51
  139. data/spec/watirspec/special_chars_spec.rb +0 -23
@@ -2,194 +2,201 @@
2
2
 
3
3
  require_relative '../unit_helper'
4
4
 
5
- describe Watir::Locators::TextField::SelectorBuilder do
6
- include LocatorSpecHelper
7
-
8
- let(:selector_builder) { described_class.new(attributes, query_scope) }
9
- let(:uppercase) { 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ' }
10
- let(:lowercase) { 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ' }
11
- let(:negative_types) do
12
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('file','#{uppercase}','#{lowercase}') and " \
13
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('radio','#{uppercase}','#{lowercase}') and " \
14
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('checkbox','#{uppercase}','#{lowercase}') and " \
15
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('submit','#{uppercase}','#{lowercase}') and " \
16
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('reset','#{uppercase}','#{lowercase}') and " \
17
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('image','#{uppercase}','#{lowercase}') and " \
18
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('button','#{uppercase}','#{lowercase}') and " \
19
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('hidden','#{uppercase}','#{lowercase}') and " \
20
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('range','#{uppercase}','#{lowercase}') and " \
21
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('color','#{uppercase}','#{lowercase}') and " \
22
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('date','#{uppercase}','#{lowercase}') and " \
23
- "translate(@type,'#{uppercase}','#{lowercase}')!=translate('datetime-local','#{uppercase}','#{lowercase}')"
24
- end
25
-
26
- describe '#build' do
27
- it 'without any arguments' do
28
- selector = {}
29
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
30
-
31
- expect(selector_builder.build(selector)).to eq built
32
- end
33
-
34
- context 'with type' do
35
- it 'specified text field type that is text' do
36
- selector = {type: 'text'}
37
- built = {xpath: ".//*[local-name()='input']" \
38
- "[translate(@type,'#{uppercase}','#{lowercase}')=" \
39
- "translate('text','#{uppercase}','#{lowercase}')]"}
40
-
41
- expect(selector_builder.build(selector)).to eq built
42
- end
43
-
44
- it 'specified text field type that is not text' do
45
- selector = {type: 'number'}
46
- built = {xpath: ".//*[local-name()='input']" \
47
- "[translate(@type,'#{uppercase}','#{lowercase}')=" \
48
- "translate('number','#{uppercase}','#{lowercase}')]"}
49
-
50
- expect(selector_builder.build(selector)).to eq built
51
- end
52
-
53
- it 'true locates text field with a type specified' do
54
- selector = {type: true}
55
- built = {xpath: ".//*[local-name()='input'][#{negative_types}]"}
56
-
57
- expect(selector_builder.build(selector)).to eq built
58
- end
59
-
60
- it 'false locates text field without type specified' do
61
- selector = {type: false}
62
- built = {xpath: ".//*[local-name()='input'][not(@type)]"}
63
-
64
- expect(selector_builder.build(selector)).to eq built
65
- end
66
-
67
- it 'raises exception when a non-text field type input is specified' do
68
- selector = {type: 'checkbox'}
69
- msg = 'TextField Elements can not be located by type: checkbox'
70
-
71
- expect { selector_builder.build(selector) }
72
- .to raise_exception Watir::Exception::LocatorException, msg
73
- end
74
- end
75
-
76
- context 'with index' do
77
- it 'positive' do
78
- selector = {index: 4}
79
- built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[5]"}
80
-
81
- expect(selector_builder.build(selector)).to eq built
82
- end
83
-
84
- it 'negative' do
85
- selector = {index: -3}
86
- built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()-2]"}
87
-
88
- expect(selector_builder.build(selector)).to eq built
89
- end
90
-
91
- it 'last' do
92
- selector = {index: -1}
93
- built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()]"}
94
-
95
- expect(selector_builder.build(selector)).to eq built
96
- end
97
-
98
- it 'does not return index if it is zero' do
99
- selector = {index: 0}
100
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
101
-
102
- expect(selector_builder.build(selector)).to eq built
103
- end
104
-
105
- it 'raises exception when index is not an Integer' do
106
- selector = {index: 'foo'}
107
- msg = /expected one of \[(Integer|Fixnum)\], got "foo":String/
108
-
109
- expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
110
- end
111
- end
112
-
113
- context 'with wrong tag name' do
114
- # TODO: Should this throw exception?
115
- it 'ignores tag name' do
116
- selector = {tag_name: 'div'}
117
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
118
-
119
- expect(selector_builder.build(selector)).to eq built
120
- end
121
- end
122
-
123
- context 'with text' do
124
- it 'String for value' do
125
- selector = {text: 'Developer'}
126
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: 'Developer'}
127
-
128
- expect(selector_builder.build(selector)).to eq built
129
- end
130
-
131
- it 'Simple Regexp for value' do
132
- selector = {text: /Dev/}
133
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: /Dev/}
134
-
135
- expect(selector_builder.build(selector)).to eq built
136
- end
137
-
138
- it 'returns complicated Regexp to the locator as a value' do
139
- selector = {text: /^foo$/}
140
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: /^foo$/}
141
-
142
- expect(selector_builder.build(selector)).to eq built
143
- end
144
- end
145
-
146
- context 'with label' do
147
- it 'using String' do
148
- selector = {label: 'First name'}
149
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
150
- "[@id=//label[normalize-space()='First name']" \
151
- "/@for or parent::label[normalize-space()='First name']]"}
152
-
153
- expect(selector_builder.build(selector)).to eq built
154
- end
155
-
156
- it 'uses String with hidden text' do
157
- selector = {label: 'With hidden text'}
158
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
159
- "[@id=//label[normalize-space()='With hidden text']" \
160
- "/@for or parent::label[normalize-space()='With hidden text']]"}
161
-
162
- expect(selector_builder.build(selector)).to eq built
163
- end
164
-
165
- it 'using simple Regexp' do
166
- selector = {label: /First/}
167
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
168
- '[@id=//label[contains(normalize-space(), "First")]' \
169
- '/@for or parent::label[contains(normalize-space(), "First")]]'}
170
-
171
- expect(selector_builder.build(selector)).to eq built
172
- end
173
-
174
- it 'using complex Regexp' do
175
- selector = {label: /([qa])st? name/}
176
- built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
177
- '[@id=//label[contains(normalize-space(), "s") and contains(normalize-space(), " name")]' \
178
- '/@for or parent::label[contains(normalize-space(), "s") ' \
179
- 'and contains(normalize-space(), " name")]]',
180
- label_element: /([qa])st? name/}
181
-
182
- expect(selector_builder.build(selector)).to eq built
183
- end
184
- end
185
-
186
- context 'with multiple locators' do
187
- it 'locates using tag name, class, attributes and text' do
188
- selector = {text: 'Developer', class: /c/, id: true}
189
- built = {xpath: ".//*[local-name()='input'][contains(@class, \"c\")]" \
190
- "[not(@type) or (#{negative_types})][@id]", text: 'Developer'}
191
-
192
- expect(selector_builder.build(selector)).to eq built
5
+ module Watir
6
+ module Locators
7
+ class TextField
8
+ describe SelectorBuilder do
9
+ include LocatorSpecHelper
10
+
11
+ let(:selector_builder) { described_class.new(attributes, query_scope) }
12
+ let(:uppercase) { 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ' }
13
+ let(:lowercase) { 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ' }
14
+ let(:negative_types) do
15
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('file','#{uppercase}','#{lowercase}') and " \
16
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('radio','#{uppercase}','#{lowercase}') and " \
17
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('checkbox','#{uppercase}','#{lowercase}') and " \
18
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('submit','#{uppercase}','#{lowercase}') and " \
19
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('reset','#{uppercase}','#{lowercase}') and " \
20
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('image','#{uppercase}','#{lowercase}') and " \
21
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('button','#{uppercase}','#{lowercase}') and " \
22
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('hidden','#{uppercase}','#{lowercase}') and " \
23
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('range','#{uppercase}','#{lowercase}') and " \
24
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('color','#{uppercase}','#{lowercase}') and " \
25
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('date','#{uppercase}','#{lowercase}') and " \
26
+ "translate(@type,'#{uppercase}','#{lowercase}')!=translate('datetime-local','#{uppercase}','#{lowercase}')"
27
+ end
28
+
29
+ describe '#build' do
30
+ it 'without any arguments' do
31
+ selector = {}
32
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
33
+
34
+ expect(selector_builder.build(selector)).to eq built
35
+ end
36
+
37
+ context 'with type' do
38
+ it 'specified text field type that is text' do
39
+ selector = {type: 'text'}
40
+ built = {xpath: ".//*[local-name()='input']" \
41
+ "[translate(@type,'#{uppercase}','#{lowercase}')=" \
42
+ "translate('text','#{uppercase}','#{lowercase}')]"}
43
+
44
+ expect(selector_builder.build(selector)).to eq built
45
+ end
46
+
47
+ it 'specified text field type that is not text' do
48
+ selector = {type: 'number'}
49
+ built = {xpath: ".//*[local-name()='input']" \
50
+ "[translate(@type,'#{uppercase}','#{lowercase}')=" \
51
+ "translate('number','#{uppercase}','#{lowercase}')]"}
52
+
53
+ expect(selector_builder.build(selector)).to eq built
54
+ end
55
+
56
+ it 'true locates text field with a type specified' do
57
+ selector = {type: true}
58
+ built = {xpath: ".//*[local-name()='input'][#{negative_types}]"}
59
+
60
+ expect(selector_builder.build(selector)).to eq built
61
+ end
62
+
63
+ it 'false locates text field without type specified' do
64
+ selector = {type: false}
65
+ built = {xpath: ".//*[local-name()='input'][not(@type)]"}
66
+
67
+ expect(selector_builder.build(selector)).to eq built
68
+ end
69
+
70
+ it 'raises exception when a non-text field type input is specified' do
71
+ selector = {type: 'checkbox'}
72
+ msg = 'TextField Elements can not be located by type: checkbox'
73
+
74
+ expect { selector_builder.build(selector) }
75
+ .to raise_exception Watir::Exception::LocatorException, msg
76
+ end
77
+ end
78
+
79
+ context 'with index' do
80
+ it 'positive' do
81
+ selector = {index: 4}
82
+ built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[5]"}
83
+
84
+ expect(selector_builder.build(selector)).to eq built
85
+ end
86
+
87
+ it 'negative' do
88
+ selector = {index: -3}
89
+ built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()-2]"}
90
+
91
+ expect(selector_builder.build(selector)).to eq built
92
+ end
93
+
94
+ it 'last' do
95
+ selector = {index: -1}
96
+ built = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()]"}
97
+
98
+ expect(selector_builder.build(selector)).to eq built
99
+ end
100
+
101
+ it 'does not return index if it is zero' do
102
+ selector = {index: 0}
103
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
104
+
105
+ expect(selector_builder.build(selector)).to eq built
106
+ end
107
+
108
+ it 'raises exception when index is not an Integer' do
109
+ selector = {index: 'foo'}
110
+ msg = /expected one of \[(Integer|Fixnum)\], got "foo":String/
111
+
112
+ expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
113
+ end
114
+ end
115
+
116
+ context 'with wrong tag name' do
117
+ # TODO: Should this throw exception?
118
+ it 'ignores tag name' do
119
+ selector = {tag_name: 'div'}
120
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
121
+
122
+ expect(selector_builder.build(selector)).to eq built
123
+ end
124
+ end
125
+
126
+ context 'with text' do
127
+ it 'String for value' do
128
+ selector = {text: 'Developer'}
129
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: 'Developer'}
130
+
131
+ expect(selector_builder.build(selector)).to eq built
132
+ end
133
+
134
+ it 'Simple Regexp for value' do
135
+ selector = {text: /Dev/}
136
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: /Dev/}
137
+
138
+ expect(selector_builder.build(selector)).to eq built
139
+ end
140
+
141
+ it 'returns complicated Regexp to the locator as a value' do
142
+ selector = {text: /^foo$/}
143
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]", text: /^foo$/}
144
+
145
+ expect(selector_builder.build(selector)).to eq built
146
+ end
147
+ end
148
+
149
+ context 'with label' do
150
+ it 'using String' do
151
+ selector = {label: 'First name'}
152
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
153
+ "[@id=//label[normalize-space()='First name']" \
154
+ "/@for or parent::label[normalize-space()='First name']]"}
155
+
156
+ expect(selector_builder.build(selector)).to eq built
157
+ end
158
+
159
+ it 'uses String with hidden text' do
160
+ selector = {label: 'With hidden text'}
161
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
162
+ "[@id=//label[normalize-space()='With hidden text']" \
163
+ "/@for or parent::label[normalize-space()='With hidden text']]"}
164
+
165
+ expect(selector_builder.build(selector)).to eq built
166
+ end
167
+
168
+ it 'using simple Regexp' do
169
+ selector = {label: /First/}
170
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
171
+ '[@id=//label[contains(normalize-space(), "First")]' \
172
+ '/@for or parent::label[contains(normalize-space(), "First")]]'}
173
+
174
+ expect(selector_builder.build(selector)).to eq built
175
+ end
176
+
177
+ it 'using complex Regexp' do
178
+ selector = {label: /([qa])st? name/}
179
+ built = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]" \
180
+ '[@id=//label[contains(normalize-space(), "s") and ' \
181
+ 'contains(normalize-space(), " name")]' \
182
+ '/@for or parent::label[contains(normalize-space(), "s") ' \
183
+ 'and contains(normalize-space(), " name")]]',
184
+ label_element: /([qa])st? name/}
185
+
186
+ expect(selector_builder.build(selector)).to eq built
187
+ end
188
+ end
189
+
190
+ context 'with multiple locators' do
191
+ it 'locates using tag name, class, attributes and text' do
192
+ selector = {text: 'Developer', class: /c/, id: true}
193
+ built = {xpath: ".//*[local-name()='input'][contains(@class, \"c\")]" \
194
+ "[not(@type) or (#{negative_types})][@id]", text: 'Developer'}
195
+
196
+ expect(selector_builder.build(selector)).to eq built
197
+ end
198
+ end
199
+ end
193
200
  end
194
201
  end
195
202
  end
@@ -2,25 +2,33 @@
2
2
 
3
3
  require_relative '../unit_helper'
4
4
 
5
- describe Watir::Locators::TextArea::SelectorBuilder do
6
- include LocatorSpecHelper
5
+ module Watir
6
+ module Locators
7
+ class TextArea
8
+ describe SelectorBuilder do
9
+ include LocatorSpecHelper
7
10
 
8
- let(:selector_builder) { described_class.new(attributes, query_scope) }
11
+ let(:selector_builder) { described_class.new(attributes, query_scope) }
9
12
 
10
- describe '#build' do
11
- context 'Always returns value argument' do
12
- it 'String' do
13
- selector = {tag_name: 'textarea', value: 'Foo'}
14
- built = {xpath: ".//*[local-name()='textarea']", value: 'Foo'}
13
+ describe '#build' do
14
+ context 'when String value' do
15
+ it 'returns value argument' do
16
+ selector = {tag_name: 'textarea', value: 'Foo'}
17
+ built = {xpath: ".//*[local-name()='textarea']", value: 'Foo'}
15
18
 
16
- expect(selector_builder.build(selector)).to eq built
17
- end
19
+ expect(selector_builder.build(selector)).to eq built
20
+ end
21
+ end
18
22
 
19
- it 'Regexp' do
20
- selector = {tag_name: 'textarea', value: /Foo/}
21
- built = {xpath: ".//*[local-name()='textarea']", value: /Foo/}
23
+ context 'when Regexp value' do
24
+ it 'returns value argument' do
25
+ selector = {tag_name: 'textarea', value: /Foo/}
26
+ built = {xpath: ".//*[local-name()='textarea']", value: /Foo/}
22
27
 
23
- expect(selector_builder.build(selector)).to eq built
28
+ expect(selector_builder.build(selector)).to eq built
29
+ end
30
+ end
31
+ end
24
32
  end
25
33
  end
26
34
  end
@@ -2,94 +2,98 @@
2
2
 
3
3
  require_relative 'unit_helper'
4
4
 
5
- describe Watir::Wait do
6
- describe '#until' do
7
- it 'waits until the block returns true' do
8
- Watir::Wait.until(timeout: 0.5) { @result = true }
9
- expect(@result).to be true
5
+ module Watir
6
+ describe Wait do
7
+ describe '#until' do
8
+ it 'waits until the block returns true' do
9
+ described_class.until(timeout: 0.5) { @result = true }
10
+ expect(@result).to be true
11
+ end
12
+
13
+ it 'executes block if timeout is zero' do
14
+ described_class.until(timeout: 0) { @result = true }
15
+ expect(@result).to be true
16
+ end
17
+
18
+ it 'times out' do
19
+ expect { described_class.until(timeout: 0.5) { false } }.to raise_error(Watir::Wait::TimeoutError)
20
+ end
21
+
22
+ it 'times out with a custom message' do
23
+ expect {
24
+ described_class.until(timeout: 0.5, message: 'oops') { false }
25
+ }.to raise_error(Watir::Wait::TimeoutError, 'timed out after 0.5 seconds, oops')
26
+ end
27
+
28
+ it 'uses provided interval' do
29
+ expect {
30
+ described_class.until(timeout: 0.4, interval: 0.2) do
31
+ @result = @result.nil? ? 1 : @result + 1
32
+ false
33
+ end
34
+ }.to raise_timeout_exception
35
+ expect(@result).to eq 2
36
+ end
37
+
38
+ it 'uses timer for waiting' do
39
+ timer = described_class.timer
40
+ allow(timer).to receive(:wait).and_call_original
41
+ described_class.until(timeout: 0.5) { true }
42
+ expect(timer).to have_received(:wait).with(0.5)
43
+ end
10
44
  end
11
45
 
12
- it 'executes block if timeout is zero' do
13
- Watir::Wait.until(timeout: 0) { @result = true }
14
- expect(@result).to be true
46
+ describe '#while' do
47
+ it 'waits while the block returns true' do
48
+ expect(described_class.while(timeout: 0.5) { false }).to be_nil
49
+ end
50
+
51
+ it 'executes block if timeout is zero' do
52
+ expect(described_class.while(timeout: 0) { false }).to be_nil
53
+ end
54
+
55
+ it 'times out' do
56
+ expect { described_class.while(timeout: 0.5) { true } }.to raise_error(Watir::Wait::TimeoutError)
57
+ end
58
+
59
+ it 'times out with a custom message' do
60
+ expect {
61
+ described_class.while(timeout: 0.5, message: 'oops') { true }
62
+ }.to raise_error(Watir::Wait::TimeoutError, 'timed out after 0.5 seconds, oops')
63
+ end
64
+
65
+ it 'uses provided interval' do
66
+ expect {
67
+ described_class.while(timeout: 0.4, interval: 0.2) do
68
+ @result = @result.nil? ? 1 : @result + 1
69
+ true
70
+ end
71
+ }.to raise_timeout_exception
72
+ expect(@result).to eq 2
73
+ end
74
+
75
+ it 'uses timer for waiting' do
76
+ timer = described_class.timer
77
+ allow(timer).to receive(:wait).and_call_original
78
+ described_class.while(timeout: 0.5) { false }
79
+ expect(timer).to have_received(:wait).with(0.5)
80
+ end
15
81
  end
16
82
 
17
- it 'times out' do
18
- expect { Watir::Wait.until(timeout: 0.5) { false } }.to raise_error(Watir::Wait::TimeoutError)
83
+ describe '#timer' do
84
+ it 'returns default timer' do
85
+ expect(described_class.timer).to be_a(Watir::Wait::Timer)
86
+ end
19
87
  end
20
88
 
21
- it 'times out with a custom message' do
22
- expect {
23
- Watir::Wait.until(timeout: 0.5, message: 'oops') { false }
24
- }.to raise_error(Watir::Wait::TimeoutError, 'timed out after 0.5 seconds, oops')
25
- end
26
-
27
- it 'uses provided interval' do
28
- expect {
29
- Watir::Wait.until(timeout: 0.4, interval: 0.2) do
30
- @result = @result.nil? ? 1 : @result + 1
31
- false
32
- end
33
- }.to raise_timeout_exception
34
- expect(@result).to eq 2
35
- end
36
-
37
- it 'uses timer for waiting' do
38
- timer = Watir::Wait.timer
39
- expect(timer).to receive(:wait).with(0.5).and_call_original
40
- Watir::Wait.until(timeout: 0.5) { true }
41
- end
42
- end
43
-
44
- describe '#while' do
45
- it 'waits while the block returns true' do
46
- expect(Watir::Wait.while(timeout: 0.5) { false }).to be_nil
47
- end
48
-
49
- it 'executes block if timeout is zero' do
50
- expect(Watir::Wait.while(timeout: 0) { false }).to be_nil
51
- end
52
-
53
- it 'times out' do
54
- expect { Watir::Wait.while(timeout: 0.5) { true } }.to raise_error(Watir::Wait::TimeoutError)
55
- end
56
-
57
- it 'times out with a custom message' do
58
- expect {
59
- Watir::Wait.while(timeout: 0.5, message: 'oops') { true }
60
- }.to raise_error(Watir::Wait::TimeoutError, 'timed out after 0.5 seconds, oops')
61
- end
62
-
63
- it 'uses provided interval' do
64
- expect {
65
- Watir::Wait.while(timeout: 0.4, interval: 0.2) do
66
- @result = @result.nil? ? 1 : @result + 1
67
- true
68
- end
69
- }.to raise_timeout_exception
70
- expect(@result).to eq 2
71
- end
72
-
73
- it 'uses timer for waiting' do
74
- timer = Watir::Wait.timer
75
- expect(timer).to receive(:wait).with(0.5).and_call_original
76
- Watir::Wait.while(timeout: 0.5) { false }
77
- end
78
- end
79
-
80
- describe '#timer' do
81
- it 'returns default timer' do
82
- expect(Watir::Wait.timer).to be_a(Watir::Wait::Timer)
83
- end
84
- end
85
-
86
- describe '#timer=' do
87
- after { Watir::Wait.timer = nil }
89
+ describe '#timer=' do
90
+ after { described_class.timer = nil }
88
91
 
89
- it 'changes default timer' do
90
- timer = Class.new
91
- Watir::Wait.timer = timer
92
- expect(Watir::Wait.timer).to eq(timer)
92
+ it 'changes default timer' do
93
+ timer = Class.new
94
+ described_class.timer = timer
95
+ expect(described_class.timer).to eq(timer)
96
+ end
93
97
  end
94
98
  end
95
99
  end