Skip to content

Commit

Permalink
Multiselect from dropdown (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmcgarvey authored Nov 25, 2020
1 parent cf566b3 commit c495465
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 2 deletions.
32 changes: 32 additions & 0 deletions spec/lucky_flow_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,38 @@ describe LuckyFlow do
flow.select("cars", value: "ford")
flow.el("#cars").value.should eq "ford"
end

it "can choose options in multi select input" do
flow = visit_page_with <<-HTML
<select name="cars" id="cars" multiple>
<option value="ford">Ford</option>
<option value="honda">Honda</option>
<option value="tesla">Tesla</option>
<option value="toyota">Toyota</option>
</select>
HTML

flow.select("cars", value: ["honda", "toyota"])
flow.el("option[value='ford']").selected?.should be_false
flow.el("option[value='honda']").selected?.should be_true
flow.el("option[value='tesla']").selected?.should be_false
flow.el("option[value='toyota']").selected?.should be_true
end

it "raises error if attempting to select multiple options when not multi select" do
flow = visit_page_with <<-HTML
<select name="cars" id="cars">
<option value="ford">Ford</option>
<option value="honda">Honda</option>
<option value="tesla">Tesla</option>
<option value="toyota">Toyota</option>
</select>
HTML

expect_raises(LuckyFlow::InvalidOperationError) do
flow.select("cars", value: ["honda", "toyota"])
end
end
end

private class FakeProcess
Expand Down
14 changes: 13 additions & 1 deletion src/lucky_flow.cr
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,26 @@ class LuckyFlow
# ```crystal
# select("post:category", value: "rant")
# ```
def select(name_attr : String, value : String)
#
# If given an Array(String), the select is assumed to have the 'multiple' attribute
# and will raise a `LuckyFlow::InvalidMultiSelectError` if it doesn't.
#
# ```crystal
# select("post:tags", value: ["rant", "technology"])
# ```
#
def select(name_attr : String, value : Array(String) | String)
self.select(field(name_attr), value: value)
end

def select(element : Element, value : String)
element.select_option(value)
end

def select(element : Element, value : Array(String))
element.select_options(value)
end

# Fill a form created by Lucky that uses an Avram::SaveOperation
#
# Note that Lucky and Avram are required to use this method
Expand Down
9 changes: 8 additions & 1 deletion src/lucky_flow/element.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class LuckyFlow::Element
private getter raw_selector
getter inner_text
delegate text, click, send_keys, displayed?, attribute, property, tag_name, to: element
delegate text, click, send_keys, displayed?, selected?, attribute, property, tag_name, to: element
delegate session, to: LuckyFlow

def initialize(@raw_selector : String, text @inner_text : String? = nil)
Expand Down Expand Up @@ -54,4 +54,11 @@ class LuckyFlow::Element
select_el = Selenium::Helpers::Select.from_element(element)
select_el.select_by_value(value)
end

def select_options(values : Array(String))
select_el = Selenium::Helpers::Select.from_element(element)
raise LuckyFlow::InvalidMultiSelectError.new unless select_el.multiple?

values.each { |value| select_el.select_by_value(value) }
end
end
9 changes: 9 additions & 0 deletions src/lucky_flow/errors.cr
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,13 @@ class LuckyFlow
super message
end
end

class InvalidOperationError < Error
end

class InvalidMultiSelectError < InvalidOperationError
def initialize
super "Unable to select multiple options when select element does not have 'multiple' attribute"
end
end
end

0 comments on commit c495465

Please sign in to comment.