Assertions using `LiveViewTest.page_title/1` require HTML escaping, unless page was patched
Environment
- Elixir version (elixir -v): Elixir 1.16.1 (compiled with Erlang/OTP 26)
- Phoenix version (mix deps): 1.7.12
- Phoenix LiveView version (mix deps): 0.20.14
- Operating system: macOS Sonoma 14.5
- Browsers you attempted to reproduce this bug on (the more the merrier): N/A
- Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: N/A
Actual behavior
This could be intentional/known, but I couldn't find anything documenting this behavior and it seems surprising when writing tests.
Patching to a liveview route then using page_title/1 in tests does not require HTML escaping when asserting on the page title, but redirects and initial loads of a liveview page do require escaping. See this test in a sample repo, where I've fixed the user's name to be D'Angelo Smith.
Using config :floki, :encode_raw_html, false in our test config does not have an effect on this. Related link: https://johnelmlabs.com/posts/flaky-faker-liveview-tests
Expected behavior
I do not need to HTML escape when comparing the result of page_title/1, regardless of how the page was loaded.
Hmmm. So it fails initially because we get the title from the rendered HTML, where it is escaped:
https://github.com/phoenixframework/phoenix_live_view/blob/e1a1bd388d917e23a806f02aa0e8ff9a32a65d91/lib/phoenix_live_view/test/client_proxy.ex#L486-L489
But when the page is patched we store the raw value from the diff, where it is not escaped.
https://github.com/phoenixframework/phoenix_live_view/blob/e1a1bd388d917e23a806f02aa0e8ff9a32a65d91/lib/phoenix_live_view/test/client_proxy.ex#L1186-L1191
While there are not a lot of escaped characters (https://github.com/phoenixframework/phoenix_html/blob/81782d9a019666e6c94e4391631df8343ef867b1/lib/phoenix_html/engine.ex#L28-L34), there's no unescape function if Phoenix.HTML or Floki that we can simply invoke and I'm also not sure if we should unescape at all.
To make it consistent, we could html_escape the title from diffs as well. Then you'd need to always escape...