neurodynamic
I have a page in my Phoenix app with some LiveView code. When you click a button, it shows the Stripe credit card modal form via a Hook. It looks roughly like this:
Hooks.StripeFormButton = {
mounted() {
this.el.addEventListener("click", () => {
showStripeForm({
onSuccess: (token) => {
this.pushEvent("save-card", {token: token})
}
})
})
}
}
So a user clicks the button, fills out the Stripe form, and when they submit it, the "save-card" event gets sent to the back-end. That will save their credit card info and then render some info to show that the save was successful.
My problem is, since the click and the form submit are done through hooks instead of phx-click and phx-submit attributes, I can’t figure out a way to test them. I want to be able to write a test that says “after the "save-card" event gets triggered, a confirmation message shows on the page”. But I can’t find a way to trigger the "save-card" event in a LiveView test without using something like render_click or render_submit which won’t work since I’m not using phx-click or phx-submit for the Stripe form. Is there a push_event testing function somewhere that I’m missing in the documentation? Or is there another way to do this?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
outlog
think you’ll need to test using something like wallaby eg headless chrome/firefox.. since this requires a js runtime..
you can see https://www.tddphoenix.com for getting started - excellent resource..
could be wrong though, but don’t see how elixir side should/can know what goes on in js hooks..
neurodynamic
Something like that is definitely an option, but I’m hoping there’s a way to just trigger the event within a LiveView test in elixir. There’s no way to invoke the Stripe form or fill it out without a tool like wallaby, but it seems like there ought to be a way to simulate the
this.pushEventcall that would normally happen on the form submit.The closest I’ve been able to get so far is setting up a
handle_infofunction that works the same wayhandle_eventdoes and testing that, because withhandle_info, I can trigger it in the test like thisand if my setup looks like this
then when
handle_infotests pass, it should be a good bet thathandle_eventtests, if they were possible to write, would pass the same way. It’s hacky, but it basically works. Unfortunately, as far as I can tell, there’s no analog tosend(view.pid, {:test_save_card, "some stripe token"})that works to triggerhandle_event.amnu3387
If you have the socket in the test (I haven’t written any tests with liveview, but I imagine you have?) you can just call
YourLiveView.Module.handle_event("save-card", %{"token" => "your_token"}, the_socket)and assert on the result of save card and any side effects?This doesn’t test the client interface tough, just that if an event
"save-card"with those params are sent through the live view it works correctly.neurodynamic
Yes, I think this might work, but so far I haven’t been able to figure out how to get access to the socket in tests, either
amnu3387
Yeah probably it’s possible to build the socket manually but I didn’t see any helpers for that while giving it a quick glance. I thought it would allow as it does with channels (the phx channelcase) you have some helpers to build it though.
PJUllrich
Just FYI: There’s the render_hook/3 option now, which simulates sending an event through
this.pushEvent("foo", "bar")in your JavaScript. It will then trigger thehandle_event("foo", "bar", socket)-callback in your LiveView.So, in your use case, you could write a test like:
neurodynamic
That works perfectly; thank you!
dustin
I’d still like to know how to access the socket. I have a
handle_eventthat gets called from the browser when a user releases the mouse button after drawing a box on an image.My
handle_eventsaves the latest coordinates in the assigns and then fires back all the boxes that the user has drawn to the browser to re-render them in JavaScript. I’d love to be able to assert that the assigns has the right data after processing what came back from the browser on mouseup.sulphur
Someone know how to test
pushEventTowhen targeting component ?render_hook/3requires that component has thephx-hookon the target component however in my case i have thedivwithphx-hookoutside and it uses thepushEventTo("from", ...)to update crop zone in real time. It is a multi file upload where user before uploading can crop all images in order to select required zone with correct aspect. So to test it i need to execute thehandle_eventon myFormComponent.And when i do
I have error that
element selected by "form" does not have phx-hook attribute. which is true of course because hook is outside.I have something like that :
unyraw
Bit of a late answer, but could potentially help someone coming across this post :
You need to target the element with
phx-hookattached to it. In your case it would be the div(s) you perform the iteration on.Also, if your code resides in a
Live Componentand you don’t want thepushEventToto be sent to the parent, you need to add aphx-target={@myself}on the targetted element.