Skip to content

Commit 2f4a8cf

Browse files
committed
Rename config option, slight refactoring, improve sandbox tests
1 parent 3b54699 commit 2f4a8cf

File tree

6 files changed

+53
-25
lines changed

6 files changed

+53
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
99
### Changed
1010
- Ecto sandbox ownership: Use a separate sandbox owner process instead of the test process. This reduces ownership errors when LiveViews continue to use database connections after the test terminates. Commit [7577d5e]
1111
### Added
12-
- Config option `sandbox_shutdown_delay`: Delay in milliseconds before shutting down the Ecto sandbox owner. Use when LiveViews or other processes need time to stop using the connections. Commit [7577d5e]
12+
- Config option `ecto_sandbox_stop_owner_delay`: Delay in milliseconds before shutting down the Ecto sandbox owner. Use when LiveViews or other processes need time to stop using the connections. Commit [7577d5e]
1313

1414
## [0.9.1] 2025-10-29
1515
### Added

lib/phoenix_test/playwright.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ defmodule PhoenixTest.Playwright do
189189
** (DBConnection.OwnershipError) cannot find owner for ...
190190
```
191191
192-
To prevent this, the `sandbox_shutdown_delay` option allows you to delay the
192+
To prevent this, the `ecto_sandbox_stop_owner_delay` option allows you to delay the
193193
sandbox owner's shutdown, giving LiveViews and other processes time to close
194194
their database connections. The delay happens during
195195
`ExUnit.Callbacks.on_exit/1`, which blocks the running of the next test, so
@@ -200,7 +200,7 @@ defmodule PhoenixTest.Playwright do
200200
tests that need it, using `@tag` (or `@describetag` or `@moduletag`) like:
201201
202202
```
203-
@tag sandbox_shutdown_delay: 100 # 100ms
203+
@tag ecto_sandbox_stop_owner_delay: 100 # 100ms
204204
test "does something" do
205205
# ...
206206
end
@@ -212,7 +212,7 @@ defmodule PhoenixTest.Playwright do
212212
```elixir
213213
# config/test.exs
214214
config :phoenix_test, playwright: [
215-
sandbox_shutdown_delay: 50 # 50ms
215+
ecto_sandbox_stop_owner_delay: 50 # 50ms
216216
]
217217
```
218218

lib/phoenix_test/playwright/case.ex

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,15 @@ defmodule PhoenixTest.Playwright.Case do
171171
repos = Application.get_env(otp_app, :ecto_repos, [])
172172

173173
repos
174-
|> Enum.map(&maybe_start_sandbox_owner(&1, context, config))
174+
|> Enum.map(&maybe_start_sandbox_owner(&1, config, context))
175175
|> Phoenix.Ecto.SQL.Sandbox.metadata_for(self())
176176
|> Phoenix.Ecto.SQL.Sandbox.encode_metadata()
177177
end
178178

179-
defp maybe_start_sandbox_owner(repo, context, config) do
179+
defp maybe_start_sandbox_owner(repo, config, context) do
180180
case start_sandbox_owner(repo, context) do
181181
{:ok, pid} ->
182-
on_exit(fn -> stop_sandbox_owner(pid, config[:sandbox_shutdown_delay], context.async) end)
182+
on_exit(fn -> stop_sandbox_owner(pid, config, context) end)
183183

184184
_ ->
185185
:ok
@@ -189,21 +189,22 @@ defmodule PhoenixTest.Playwright.Case do
189189
end
190190

191191
defp start_sandbox_owner(repo, context) do
192-
pid = Sandbox.start_owner!(repo, shared: !context.async)
192+
pid = Sandbox.start_owner!(repo, shared: not context.async)
193193
{:ok, pid}
194194
rescue
195195
_ -> {:error, :probably_already_started}
196196
end
197197

198-
defp stop_sandbox_owner(checkout_pid, delay, async?) do
199-
if async? do
200-
spawn(fn -> do_stop_sandbox_owner(checkout_pid, delay) end)
198+
defp stop_sandbox_owner(checkout_pid, config, context) do
199+
if context.async do
200+
spawn(fn -> do_stop_sandbox_owner(checkout_pid, config) end)
201201
else
202-
do_stop_sandbox_owner(checkout_pid, delay)
202+
do_stop_sandbox_owner(checkout_pid, config)
203203
end
204204
end
205205

206-
defp do_stop_sandbox_owner(checkout_pid, delay) do
206+
defp do_stop_sandbox_owner(checkout_pid, config) do
207+
delay = Keyword.fetch!(config, :ecto_sandbox_stop_owner_delay)
207208
if delay > 0, do: Process.sleep(delay)
208209
Sandbox.stop_owner(checkout_pid)
209210
end

lib/phoenix_test/playwright/config.ex

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ schema_opts = [
101101
type: {:custom, PhoenixTest.Playwright.Config, :__validate_cli__, []},
102102
deprecated: "Use `assets_dir` instead."
103103
],
104+
ecto_sandbox_stop_owner_delay: [
105+
default: 0,
106+
type: :non_neg_integer,
107+
doc: """
108+
Delay in milliseconds before shutting down the Ecto sandbox owner after a
109+
test ends. Use this to allow LiveViews and other processes in your app
110+
time to stop using database connections before the sandbox owner is
111+
terminated.
112+
"""
113+
],
104114
executable_path: browser_opts[:executable_path],
105115
headless: browser_opts[:headless],
106116
js_logger: [
@@ -119,16 +129,6 @@ schema_opts = [
119129
Accepts either a binary executable exposed in PATH or the absolute path to it.
120130
"""
121131
],
122-
sandbox_shutdown_delay: [
123-
default: 0,
124-
type: :non_neg_integer,
125-
doc: """
126-
Delay in milliseconds before shutting down the Ecto sandbox owner after a
127-
test ends. Use this to allow LiveViews and other processes in your app
128-
time to stop using database connections before the sandbox owner is
129-
terminated. Default is 0 (immediate shutdown).
130-
"""
131-
],
132132
screenshot: [
133133
default: false,
134134
type: {:or, [:boolean, non_empty_keyword_list: screenshot_opts_schema]},
@@ -169,7 +169,7 @@ schema_opts = [
169169
schema = NimbleOptions.new!(schema_opts)
170170

171171
setup_all_keys = ~w(browser_pool browser browser_launch_timeout executable_path headless slow_mo)a
172-
setup_keys = ~w(accept_dialogs sandbox_shutdown_delay screenshot trace browser_context_opts browser_page_opts)a
172+
setup_keys = ~w(accept_dialogs ecto_sandbox_stop_owner_delay screenshot trace browser_context_opts browser_page_opts)a
173173

174174
defmodule PhoenixTest.Playwright.Config do
175175
@moduledoc """
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
defmodule PhoenixTest.Playwright.EctoSandboxAsyncFalseTest do
2+
use PhoenixTest.Playwright.Case, async: false
3+
4+
for delay_ms <- [0, 100] do
5+
@delay_ms delay_ms
6+
7+
describe "delay: #{delay_ms}ms requires ecto_sandbox_stop_owner_delay to prevent 'is still using a connection from owner' errors" do
8+
@describetag ecto_sandbox_stop_owner_delay: delay_ms + 100
9+
10+
setup %{conn: conn} do
11+
[conn: visit(conn, "/pw/live/ecto?delay_ms=#{@delay_ms}")]
12+
end
13+
14+
test "shows version", %{conn: conn} do
15+
assert_has(conn, "div", text: "Version: PostgreSQL")
16+
end
17+
18+
test "shows long running query result", %{conn: conn} do
19+
assert_has(conn, "div", text: "Long running: void")
20+
end
21+
22+
test "shows delayed version", %{conn: conn} do
23+
assert_has(conn, "div", text: "Delayed version: PostgreSQL")
24+
end
25+
end
26+
end
27+
end

test/phoenix_test/playwright/ecto_sandbox_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule PhoenixTest.Playwright.EctoSandboxTest do
33

44
for delay_ms <- [0, 100] do
55
@delay_ms delay_ms
6-
describe "delay: #{delay_ms}ms" do
6+
describe "delay: #{delay_ms}ms does not require ecto_sandbox_stop_owner_delay" do
77
setup %{conn: conn} do
88
[conn: visit(conn, "/pw/live/ecto?delay_ms=#{@delay_ms}")]
99
end

0 commit comments

Comments
 (0)