diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index ed9145d..707fa91 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -1619,35 +1619,49 @@ describe Capybara::Webkit::Driver do + + HTML end + def logged_events + driver.find_xpath("//li").map(&:visible_text) + end + before { visit("/") } let(:newtext) { '12345' } @@ -1664,29 +1678,49 @@ describe Capybara::Webkit::Driver do it "triggers text input events on inputs of type #{field_type}" do driver.find_xpath("//input[@type='#{field_type}']").first.set(newtext) driver.find_xpath("//body").first.click - expect(driver.find_xpath("//li").map(&:visible_text)).to eq textevents + expect(logged_events).to eq textevents end end it "triggers events for cleared inputs" do driver.find_xpath("//input[@type='text']").first.set('') driver.find_xpath("//body").first.click - expect(driver.find_xpath("//li").map(&:visible_text)).to include('change') + expect(logged_events).to include("change") end it "triggers textarea input events" do driver.find_xpath("//textarea").first.set(newtext) - expect(driver.find_xpath("//li").map(&:visible_text)).to eq keyevents + expect(logged_events).to eq keyevents end it "triggers radio input events" do driver.find_xpath("//input[@type='radio']").first.set(true) - expect(driver.find_xpath("//li").map(&:visible_text)).to eq %w(mousedown focus mouseup change click) + expect(logged_events).to eq %w(mousedown focus mouseup change click) end it "triggers checkbox events" do driver.find_xpath("//input[@type='checkbox']").first.set(true) - expect(driver.find_xpath("//li").map(&:visible_text)).to eq %w(mousedown focus mouseup change click) + expect(logged_events).to eq %w(mousedown focus mouseup change click) + end + + it "triggers select events" do + driver.find_xpath("//option[text() = 'Single Option 2']").first.select_option + expect(logged_events).to eq %w[single.mousedown single.focus single.input single.change single.mouseup single.click] + end + + it "triggers correct unselect events for multiple selects" do + driver.find_xpath("//option[text() = 'Multiple Option 2']").first.unselect_option + expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.change multiple.mouseup multiple.click] + end + + it "triggers correct unselect events for multiple selects when already unselected" do + driver.find_xpath("//option[text() = 'Multiple Option 3']").first.unselect_option + expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.mouseup multiple.click] + end + + it "triggers correct select events for multiple selects when additional option is selected" do + driver.find_xpath("//option[text() = 'Multiple Option 4']").first.select_option + expect(logged_events).to eq %w[multiple.mousedown multiple.focus multiple.input multiple.change multiple.mouseup multiple.click] end end diff --git a/src/capybara.js b/src/capybara.js index c1bb814..2954cfd 100644 --- a/src/capybara.js +++ b/src/capybara.js @@ -391,7 +391,15 @@ Capybara = { elem.focus(); }, - selectOption: function(index) { + selectOption: function(index){ + this._setOption(index, true); + }, + + unselectOption: function(index){ + this._setOption(index, false); + }, + + _setOption: function(index, state) { var optionNode = this.getNode(index); var selectNode = optionNode.parentNode; if (selectNode.tagName == "OPTGROUP") @@ -400,23 +408,22 @@ Capybara = { if (optionNode.disabled) return; + if ((!selectNode.multiple) && (!state)) + return; + // click on select list this.triggerOnNode(selectNode, 'mousedown'); selectNode.focus(); + this.triggerOnNode(selectNode, 'input'); + + // select/deselect option from list + if (optionNode.selected != state){ + optionNode.selected = state; + this.triggerOnNode(selectNode, 'change'); + } + this.triggerOnNode(selectNode, 'mouseup'); this.triggerOnNode(selectNode, 'click'); - - // select option from list - this.triggerOnNode(optionNode, 'mousedown'); - optionNode.selected = true; - this.triggerOnNode(selectNode, 'change'); - this.triggerOnNode(optionNode, 'mouseup'); - this.triggerOnNode(optionNode, 'click'); - }, - - unselectOption: function(index) { - this.getNode(index).selected = false; - this.trigger(index, "change"); }, centerPosition: function(element) {