Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support triggering slinky html listeners programmatically (for unit testing) #249

Closed
evbo opened this issue Mar 20, 2019 · 4 comments
Closed

Comments

@evbo
Copy link

evbo commented Mar 20, 2019

For my unit tests to trigger behavior of my components, I'd like to be able to programmatically trigger slinky event listeners as can be done with vanilla javascript:
https://stackoverflow.com/a/23612498/1080804
https://stackoverflow.com/a/42554283/1080804

However, in trying to follow those examples or this react codepen, change events only fire with direct interaction from the user, not with programmatically dispatched events:

// in rendering section of functionalComponent ...
val myInput: ReactRef[Element] = React.createRef[Element]
input(className := "form-control", ref := myInput, `type` := "number", onChange := handleChange _)

// in my handleChange function
val event = js.Dynamic.newInstance(js.Dynamic.global.CustomEvent)(
            "input",
            js.Dynamic.literal(bubbles = true)
          ).asInstanceOf[CustomEvent]
myInput.current.asInstanceOf[HTMLInputElement].dispatchEvent(event)

Or equivalently in chrome console:

// get the component in the dom:
var myInput = document.evaluate('//*[@id="root"]/div/input',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue
myInput.dispatchEvent(new CustomEvent("change"));

The above is correctly dispatching an event, but the callback defined in my slinky HTMLInputElement input never fires.

However, I can call an onchange if I set it not using slinky/react:

var v = function(){console.log('FIRE')};
myInput.setAttribute("onchange", "v()");
myInput.dispatchEvent(new CustomEvent('change'));

I see that react has it's own event for input changes, 'input'. Still I'm not able to trigger the onChange callback when dispatching input either.

Am I close? Or is the best way to do this by writing a facade for ReactDom test utils?

@evbo evbo changed the title Support triggering slinky onChange listener programmatically (for unit testing) Support triggering slinky html listeners programmatically (for unit testing) Mar 20, 2019
@shadaj
Copy link
Owner

shadaj commented Mar 21, 2019

React actually has a bunch of quirks with how it listens to input events (see https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-onchange-event-in-react-js). Writing a facade for the test utils would probably be the best path.

If you're interested in contributing a facade, I would be glad to merge it in to slinky-web!

@evbo
Copy link
Author

evbo commented Apr 3, 2019

You're right, the react event system is very tricky to understand and the stackoverflow posts only scratch the surface!

It probably would have been a better use of my time figuring out a facade for test utils, but I was lazy and wrote a quick facade for a much simpler alternative

object ReactTestEvent {
  @js.native
  @JSImport("react-trigger-change", JSImport.Default)
  private object ReactTriggerChange extends js.Any

  val reactTriggerChange = ReactTriggerChange.asInstanceOf[js.Function1[js.Object, Unit]]
}

At least for now it works for my needs, but I'll likely consider test utils in the future

@evbo
Copy link
Author

evbo commented Jul 12, 2019

@shadaj I'm fine having this issue closed unless you feel Implementing test utils is a feature enhancement that applies to Slinky necessarily.

Also, the work around I've posted above gets the job done. Maybe not for all, but at least it's light weight.

@shadaj
Copy link
Owner

shadaj commented Jul 12, 2019

Yes, don't think we need a test utils within Slinky core, that would make more sense as a separate library.

@shadaj shadaj closed this as completed Jul 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants