5

I have a Hyperstack component like this:

      render do
        LI(class: class_names, title: conflicts || '',
           data: { toggle: :tooltip, placement: 'auto left', container: :body }) do
          DIV(class: 'row paper-row') do
            DIV(class: 'col-sm-12 text-left') do
              P(class: 'medium-weight', id: 'tp_envelopes') { params.envelope.name }
            end
          end
        end.on(:click) { select_envelope }
      end

I want the on(:click) handler to be conditional if the conflicts method returns a non-nil value.

I also wonder how I can test this in hyperspec/capaybara ... i.e. how do I check to see if an html element responds to a :click event?

Mitch VanDuyn
  • 2,838
  • 1
  • 22
  • 29

4 Answers4

3

You could turn off/on the click handler conditionally by using

end.tap { |item| item.on(:click) { select_envelope } unless conflicts }

to replace

end.on(:click) { select_envelope }
2
end.on(:click) { select_envelope }

You could replace (:click) with:

(!conflicts && :click)

This works because if conflicts is not nil, this would result in a nil click handler that doesn't do anything.

1

I'm not sure that checking the element for a click event would be reliable due to event bubbling.

I would write the test to click the element, and then expect whatever logic is in the click event to not happen.

conflicts = true

element.click() # trigger select_envelope

expect(selected_envelope).to be_nil # no envelope should be selected due to conflicts
iamprich
  • 11
  • 2
1

A nice way to keep the code clean is just return inside the method called in the event:

def select_envelope
  return if conflicts

  ...
end

# this keeps the event handler the same
end.on(:click) { select_envelope }

There will be a negligible performance hit from having to always trigger the event, but there's always the debate of performance vs readability.