germsvel / phoenix_test

MIT License
144 stars 20 forks source link

Fix `assert_path`/`refute_path` to handle live patching #69

Closed germsvel closed 4 months ago

germsvel commented 4 months ago

Resolves #62

What changed?

Unlike regular page navigations and live navigations, live patching doesn't actually exhibit different behavior after a render_click or render_submit (like a live navigate does, for example).

That makes "knowing" the current path hard when a live patch has been triggered.

An ugly attempt

Live patches in LiveView tests seem to come through messages (see the assert_navigate private function). It's hard to intercept those messages since we don't own the client proxy.

An alternative route (which we take here) is to use what LiveViewTest exposes to us. And that's assert_patch/2.

The assert_patch/2 helper returns the path that we've been patched to. The downside is that it's an assertion... so it raises if nothing's been patched.

Thus, we have an implementation that -- though ugly (avert your eyes) -- rescues an assert_patch/2. In the cases where a patch has been made, we get the path back. In the cases when there was no patch to begin with, we rescue that and don't update the session.current_path.

Another potential issue is that since we're now dealing with messages, we need to choose how long we want to wait for the patch to come through. By default, assert_patch waits 100ms. But since we're potentially calling assert_patch every time we render_* (and not navigate), that could make tests a lot slower. So, we opt for waiting 0 ms -- basically saying the patch needs to have happened already. If that proves to be an issue in the future, we can try to handle it then.