How does Solid attach event handlers to DOM elements?
I want to test wether a DOM element has an onclick event handler. However, using the onclick (delgated event) in the JSX component, there is a $$click property added to the DOM element with the event handler and the onclick property is null. Using on:click (native element) on the JSX component, there is no $$click property and onclick is still null. What is the underlying mechanism for adding an event handler to DOM elements?
ref: https://docs.solidjs.com/concepts/components/event-handlers
Also, as a follow up, how would I test that an event handler is present on a DOM element? I'm currently using Vitest and Testing Library.
Thanks in advance.
5 Replies
what is the use case of testing if an element has onclick event
instead of triggering the click event and testing that the event handler you expect is called for example
testing that a handler exists seem very low level like you are testing the framework instead of your own application logic
@zulu
Great question.
I used the method you mentioned prior. I tested if the event handler was called.
However, I'm trying to follow the "test your application how it should be used, not implementation details" philosophy. Which means testing DOM elements more or less. Testing if the event handler was called is an implementation detail.
Unless I'm thinking about this incorrectly 🤷🏾♂️
in this case the event handler on the DOM is an implementation detail
as you might have seen already solid has native event and "delegated event"
in most cases this can be considered an implementation detail,
(an implementation detail you can ignore and then just test the side effect that was caused/expected by the action)
"how it should work"
will be when you click the button what do you expect to happen
if you expect a "save" action, you will test that the save was done ( or called) .
in some cases just asserting that the correct function is called with the correct arguments
can be good enough, if the functionality of the function being called is tested for its own correctness
I see. It seems I have to think about testing differently then.
I'm currently testing the component in isolation and wanted to test that the component doesn't have the event handler under certain conditions and does otherwise (based on props).
Testing what I expect to happen would be more of an integration test with other components.
I did ask in the testing channel if there is a comprehensive guide to testing a SolidJS application as I'm not sure how to effectively test following the philosophy I mentioned in my last message.
I am still curious how Solid attaches event handlers to DOM elements though.
Thanks for your help!
I will answer the question you are curious about first
native events the element will be called with the
addEventListener
el.addEventListener()
to register the handler
it will not assign the el.onClick
property of the element so you can't just check if that property is set
the case where you see $$click
is a flag set by solid for elements that are "interested" in the click event
but instead of adding event listener for each element that want to subscribe
it instead register a "top level" (on the window) event handler for the click event
and then manually traverses the path to simulate the propagation of events from the target event.
if it see an element with the $$click it will call that handler
that is the gist, might not be 100% accurate
"test your application how it should be used"
lets unpack this for a second
how is you application should be used?
is it used by the user setting click handlers and checking if the handler exists on the button ?
or it is used by the user clicking the button, and that button will do something you can assert on?
I'm currently testing the component in isolation and wanted to test that the component doesn't have the event handler under certain conditions and does otherwise (based on props).the way you can test that, is as follow: - set up the condition - trigger the click - make sure the save action was called or not based on the condition if you component is like this: then you can more easily test the component is doing what you expect because you can inject both the condition/state and the handler and then just check if it was called or not