With a small modification your code works:
try do
// some page elements action
assert visible_page_text() =~ "Hello World"
catch
error ->
take_screenshot()
raise error
end
Or turn it into a macro:
# assert screenshot on failure
defmacro assert_sof(assertion) do
quote do
try do
assert unquote(assertion)
rescue
error ->
take_screenshot()
raise error
end
end
end
And call it like this:
assert_sof visible_page_text() =~ "Hello World"
Update: As you mentioned, this will only take screenshots when doing an assertion. That can be fixed though.
Here is a macro that will wrap the contents of a whole test in a try/rescue block and save a screenshot on any error. As a bonus, it prefixes the screenshot with the name of the test. The big drawback is that you lose the stracktrace, so it's harder to pinpoint the failing line of test code. (solved with catch
instead of rescue
) Put the macro in support/conn_case.ex
or somewhere else if you prefer:
def MyAppWeb.ConnCase
# ...
# Test and take screenshot on failure. Only works for hound tests.
defmacro test_sof(message, var \\ quote do _ end, contents) do
prefix = String.replace(message, ~r/\W+/, "-")
filename = Hound.Utils.temp_file_path(prefix, "png")
quote do
test unquote(message), unquote(var) do
try do
unquote(contents)
catch
error ->
take_screenshot(unquote(filename))
raise error
end
end
end
end
using do
quote do
# Import conveniences for testing with connections
use Phoenix.ConnTest
import MyAppWeb.ConnCase, only: [test_sof: 2, test_sof: 3] # <- Add this line
# ...
end
end
# ...
end
And call it like a normal test:
test_sof "form with valid data" do
navigate_to "/form"
click({:id, "test"})
assert visible_page_text() =~ "test successful"
end
Now it should work for all kinds of errors.