elixir-wallaby / wallaby

Concurrent browser tests for your Elixir web apps.
https://twitter.com/elixir_wallaby
MIT License
1.67k stars 197 forks source link

Wallaby and Ash: dev/test env differences for `on_mount` hooks passed to `ash_authentication_live_session` #786

Closed modellurgist closed 2 months ago

modellurgist commented 2 months ago

Elixir and Erlang/OTP versions

erlang 26.1.2 elixir 1.15.7-otp-26

Operating system

MacOSX 12.7.5

Browser

Chrome

Driver

ChromeDriver

Correct Configuration

Current behavior

For a simple login test, the Ash Engine is attempting to fetch a user record from the database multiple times, without success, during the sign-in attempt using the default Ash sign-in LiveView which calls down to Ash.Form.submit.

Observations

The screenshot from Wallaby shows the app hanging at the Sign-In LiveView, with the button press leading to "Signing In" text for the button while in-process.

Wallaby requires an on_mount hook for LiveViews, but I notice that those hooks don't execute (in test MIX_ENV) when added through the ash_authentication_live_session on_mount support, whereas they do in dev env.

At first I thought the output from dbg, Logger, and/or IO.inspect calls was getting swallowed, so to be sure I wrote the debug output in those hooks to a file. test environment did not execute the hooks.

Our code in the router looks something like this:

  ash_authentication_live_session :authentication_required,
    on_mount: [
      {MyApp.LiveUserAuth, :live_user_required},
      # Needed for Wallaby support, per their docs:
      {MyAppWeb.TestSupport.AllowEctoSandbox, :default}
    ] do
    scope "/u", MyAppWeb.UserLive do

Tested with:

Expected behavior

The user should be fetch from the database and accessible in the Sign in Liveview, so it can advance after form submission.

(also posted issue here and here)

Test Code & HTML

defmodule MyAppWeb.Intentions.LoginTest do
  use ExUnit.Case, async: true
  # Note that this relies on the Wallaby macro's built-in Sandbox support
  use Wallaby.Feature

  ...

  setup context do
    # creates user
    context = context |> pipe_setup_case(MinimalSetup)

    {:ok, context}
  end

  @tag :e2e
  feature "User can sign-in and view the dashboard", %{session: session} = context do
    user_attrs = Map.get(context.users, :admin)

    session =
      session
      |> visit("/sign-in")
      |> fill_in(text_field("Email"), with: to_string(user_attrs.email))
      |> fill_in(text_field("Password"), with: user_attrs.password)
      |> click(button("Sign in"))
      |> take_screenshot()

    assert Wallaby.Browser.current_path(session) == "/dashboard"
  end
end

Demonstration Project

No response

mhanberg commented 2 months ago

This seems like an Ash issue, or I'm not understanding correctly.

zachdaniel commented 2 months ago

I added some comments on the original issue posted to ash_authentication. I don't think there would be behavior in Ash or wallaby that would affect whether hooks run in a given environment. We don't do anything special there. My suspicion is that the first hook is return {:halt, ...} causing the next hook not to run.