I’m having issues getting the sandbox plug working for my javascript based playwright tests.
I have a fairly standard and fresh phoenix app.
I wanted to create a test env similar to the standard test env, but with some tweaks for e2e tests, so I created a new config/test_ui.exs file that is a copy of the config/test.exs file but with server set to true:
import Config
# Only in tests, remove the complexity from the password hashing algorithm
config :bcrypt_elixir, :log_rounds, 1
# Configure your database
#
# The MIX_TEST_PARTITION environment variable can be used
# to provide built-in test partitioning in CI environment.
# Run `mix help test` for more information.
config :app, App.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "app_test_ui#{System.get_env("MIX_TEST_PARTITION")}",
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: System.schedulers_online() * 2,
loggers: [{Ecto.LogEntry, :log, [:debug]}]
# We don't run a server during test. If one is required,
# you can enable the server option below.
config :app, AppWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "2PQY5lqiEa9vguSZnFrprc9UrJ41GzYlSug+jskg42N+2RDSQCMPkZJ1bfddDbYv",
server: true
# In test we don't send emails
config :app, App.Mailer, adapter: Swoosh.Adapters.Test
# Disable swoosh api client as it is only required for production adapters
config :swoosh, :api_client, false
# Print only warnings and errors during test
config :logger, level: :debug
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
# Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view,
enable_expensive_runtime_checks: true
I added the ecto sandbox plug by following the docs here: Phoenix.Ecto.SQL.Sandbox — Phoenix/Ecto v4.6.3
plug Phoenix.Ecto.SQL.Sandbox,
at: /sandbox,
repo: App.Repo,
timeout: 15_000,
header: "x-app-sandbox"
I’m running it through a new mix alias:
test_ui: ["ecto.create --quiet", "ecto.migrate --quiet", "phx.server"]
Through logging, I can see that my playwright tests are properly calling /sandbox and Phoenix is getting the data back in the headers on future requests. All good there.
However, updates are being persisted to the DB as if Ecto were not in sandbox mode.
I suspect the issue is related to this line from the docs:
Finally, make sure your repository mode is set either to
:manual
or{:shared, self()}
before the external client starts. This is typically done by default in yourtest/test_helper.exs
, but you may need to do it explicitly depending on your setup:
I’m not sure where to set the sandbox to manual. Because I’m not using mix test
the test_helper.exs isn’t running. I tried to create a test_ui_helper.exs file and call that in a few differet ways, but I keep getting the error:
02:03:27.781 [error] GenServer #PID<0.645.0> terminating
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.645.0>.
When using ownership, you must manage connections in one
of the four ways:
* By explicitly checking out a connection
* By explicitly allowing a spawned process
* By running the pool in shared mode
* By using :caller option with allowed process
The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.
The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.
The fourth option requires [caller: pid] to be used when
checking out a connection from the pool. The caller process
should already be allowed on a connection.
If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.