Skip to content

Commit 3b691c4

Browse files
committed
[rb] do not allow Select class to work with disabled selects
1 parent 25b30ff commit 3b691c4

3 files changed

Lines changed: 31 additions & 23 deletions

File tree

rb/lib/selenium/webdriver/support/select.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ class Select
2626
#
2727

2828
def initialize(element)
29-
tag_name = element.tag_name
29+
unless element.enabled?
30+
raise Error::UnsupportedOperationError, 'Select element is disabled and may not be used.'
31+
end
3032

33+
tag_name = element.tag_name
3134
raise ArgumentError, "unexpected tag name #{tag_name.inspect}" unless tag_name.casecmp('select').zero?
3235

3336
@element = element

rb/spec/integration/selenium/webdriver/select_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ module Support
3030
it 'raises exception if not a select element' do
3131
expect { Select.new(driver.find_element(id: 'checky')) }.to raise_exception(ArgumentError)
3232
end
33+
34+
it 'raises exception if select is not enabled' do
35+
no_select = driver.find_element(name: 'no-select')
36+
expect { Select.new(no_select) }.to raise_exception(Error::UnsupportedOperationError)
37+
end
3338
end
3439

3540
describe '#multiple?' do

rb/spec/unit/selenium/webdriver/support/select_spec.rb

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,27 @@ module WebDriver
2424
module Support
2525
describe Select do
2626
let(:select) do
27-
select_element = instance_double(Element, tag_name: 'select')
27+
select_element = instance_double(Element, tag_name: 'select', enabled?: true)
2828
allow(select_element).to receive(:dom_attribute).with(:multiple)
2929
select_element
3030
end
3131

3232
let(:multi_select) do
33-
select_element = instance_double(Element, tag_name: 'select')
33+
select_element = instance_double(Element, tag_name: 'select', enabled?: true)
3434
allow(select_element).to receive(:dom_attribute).with(:multiple).and_return 'multiple'
3535
select_element
3636
end
3737

3838
it 'raises ArgumentError if passed a non-select Element' do
39-
link = instance_double(Element, tag_name: 'a')
39+
link = instance_double(Element, tag_name: 'a', enabled?: true)
4040

4141
expect {
4242
Select.new link
4343
}.to raise_error(ArgumentError)
4444
end
4545

4646
it 'indicates whether a select is multiple correctly' do
47-
selects = Array.new(4) { instance_double(Element, tag_name: 'select') }
47+
selects = Array.new(4) { instance_double(Element, tag_name: 'select', enabled?: true) }
4848

4949
allow(selects[0]).to receive(:dom_attribute).with(:multiple).and_return('false')
5050
allow(selects[1]).to receive(:dom_attribute).with(:multiple).and_return(nil)
@@ -69,8 +69,8 @@ module Support
6969
end
7070

7171
it 'returns all selected options' do
72-
bad_option = instance_double(Element, selected?: false)
73-
good_option = instance_double(Element, selected?: true)
72+
bad_option = instance_double(Element, selected?: false, enabled?: true)
73+
good_option = instance_double(Element, selected?: true, enabled?: true)
7474

7575
expect(multi_select).to receive(:find_elements)
7676
.with(tag_name: 'option')
@@ -84,8 +84,8 @@ module Support
8484
end
8585

8686
it 'returns the first selected option' do
87-
first_option = instance_double(Element, selected?: true)
88-
second_option = instance_double(Element, selected?: true)
87+
first_option = instance_double(Element, selected?: true, enabled?: true)
88+
second_option = instance_double(Element, selected?: true, enabled?: true)
8989

9090
expect(multi_select).to receive(:find_elements)
9191
.with(tag_name: 'option')
@@ -97,7 +97,7 @@ module Support
9797
end
9898

9999
it 'raises a NoSuchElementError if nothing is selected' do
100-
option = instance_double(Element, selected?: false)
100+
option = instance_double(Element, selected?: false, enabled?: true)
101101

102102
expect(multi_select).to receive(:find_elements)
103103
.with(tag_name: 'option')
@@ -110,7 +110,7 @@ module Support
110110
end
111111

112112
it 'allows options to be selected by visible text' do
113-
option = instance_double(Element, selected?: false)
113+
option = instance_double(Element, selected?: false, enabled?: true)
114114

115115
expect(multi_select).to receive(:find_elements)
116116
.with(xpath: './/option[normalize-space(.) = "fish"]')
@@ -123,8 +123,8 @@ module Support
123123
end
124124

125125
it 'allows options to be selected by index' do
126-
first_option = instance_double(Element, selected?: true)
127-
second_option = instance_double(Element, selected?: false)
126+
first_option = instance_double(Element, selected?: true, enabled?: true)
127+
second_option = instance_double(Element, selected?: false, enabled?: true)
128128

129129
allow(first_option).to receive(:property).with(:index).and_return 0
130130
expect(first_option).not_to receive(:click)
@@ -143,7 +143,7 @@ module Support
143143
end
144144

145145
it 'allows options to be selected by returned value' do
146-
first_option = instance_double(Element, selected?: false)
146+
first_option = instance_double(Element, selected?: false, enabled?: true)
147147
allow(multi_select).to receive(:find_elements)
148148
.with(xpath: './/option[@value = "b"]')
149149
.and_return([first_option])
@@ -155,8 +155,8 @@ module Support
155155
end
156156

157157
it 'can deselect all when select supports multiple selections' do
158-
first_option = instance_double(Element, selected?: true)
159-
second_option = instance_double(Element, selected?: false)
158+
first_option = instance_double(Element, selected?: true, enabled?: true)
159+
second_option = instance_double(Element, selected?: false, enabled?: true)
160160

161161
expect(multi_select).to receive(:find_elements)
162162
.with(tag_name: 'option')
@@ -176,8 +176,8 @@ module Support
176176
end
177177

178178
it 'can deselect options by visible text' do
179-
first_option = instance_double(Element, selected?: true)
180-
second_option = instance_double(Element, selected?: false)
179+
first_option = instance_double(Element, selected?: true, enabled?: true)
180+
second_option = instance_double(Element, selected?: false, enabled?: true)
181181

182182
allow(multi_select).to receive(:find_elements)
183183
.with(xpath: './/option[normalize-space(.) = "b"]')
@@ -191,8 +191,8 @@ module Support
191191
end
192192

193193
it 'can deselect options by index' do
194-
first_option = instance_double(Element, selected?: true)
195-
second_option = instance_double(Element)
194+
first_option = instance_double(Element, selected?: true, enabled?: true)
195+
second_option = instance_double(Element, enabled?: true)
196196

197197
allow(multi_select).to receive(:find_elements)
198198
.with(tag_name: 'option')
@@ -209,8 +209,8 @@ module Support
209209
end
210210

211211
it 'can deselect options by returned value' do
212-
first_option = instance_double(Element, selected?: true)
213-
second_option = instance_double(Element, selected?: false)
212+
first_option = instance_double(Element, selected?: true, enabled?: true)
213+
second_option = instance_double(Element, selected?: false, enabled?: true)
214214

215215
allow(multi_select).to receive(:find_elements)
216216
.with(xpath: './/option[@value = "b"]')
@@ -224,7 +224,7 @@ module Support
224224
end
225225

226226
it 'should fall back to slow lookups when "get by visible text fails" and there is a space' do
227-
first_option = instance_double(Element, selected?: false, text: 'foo bar')
227+
first_option = instance_double(Element, selected?: false, text: 'foo bar', enabled?: true)
228228

229229
xpath1 = './/option[normalize-space(.) = "foo bar"]'
230230
xpath2 = './/option[contains(., "foo")]'

0 commit comments

Comments
 (0)