查看源代码 Phoenix.LiveViewTest (Phoenix LiveView v0.20.17)

测试函数组件以及 LiveView 和 LiveComponent 的便利工具。

测试函数组件

测试函数组件有两种机制。假设有以下组件

def greet(assigns) do
  ~H"""
  <div>Hello, <%= @name %>!</div>
  """
end

可以通过使用 render_component/3 来测试它,将组件的函数引用作为第一个参数传递。

import Phoenix.LiveViewTest

test "greets" do
  assert render_component(&MyComponents.greet/1, name: "Mary") ==
           "<div>Hello, Mary!</div>"
end

但是,对于复杂的组件,通常最简单的测试方法是使用 ~H 标记本身

import Phoenix.Component
import Phoenix.LiveViewTest

test "greets" do
  assigns = %{}
  assert rendered_to_string(~H"""
         <MyComponents.greet name="Mary" />
         """) ==
           "<div>Hello, Mary!</div>"
end

区别在于使用 rendered_to_string/1 将渲染的模板转换为字符串以进行测试。

测试 LiveView 和 LiveComponent

在 LiveComponent 和 LiveView 测试中,通过进程通信来与视图交互,代替浏览器。就像浏览器一样,我们的测试进程接收有关视图渲染更新的消息,可以针对这些消息进行断言,以测试 LiveView 及其子项的生命周期和行为。

测试 LiveView

LiveView 的生命周期如 Phoenix.LiveView 文档中所述,详细说明了视图如何从断开连接的套接字状态开始作为无状态 HTML 渲染。浏览器接收到 HTML 后,将连接到服务器,并启动一个新的 LiveView 进程,在连接的套接字状态下重新挂载,视图继续以有状态方式运行。LiveView 测试函数支持分别测试断开连接和连接的挂载,例如

import Plug.Conn
import Phoenix.ConnTest
import Phoenix.LiveViewTest
@endpoint MyEndpoint

test "disconnected and connected mount", %{conn: conn} do
  conn = get(conn, "/my-path")
  assert html_response(conn, 200) =~ "<h1>My Disconnected View</h1>"

  {:ok, view, html} = live(conn)
end

test "redirected mount", %{conn: conn} do
  assert {:error, {:redirect, %{to: "/somewhere"}}} = live(conn, "my-path")
end

这里,首先使用熟悉的 Phoenix.ConnTest 函数 get/2 来测试调用挂载的常规 HTTP GET 请求,该请求使用断开的套接字。接下来,使用 live/1 调用发送的连接,以在连接状态下挂载视图,这将启动我们的有状态 LiveView 进程。

一般来说,在单个步骤中测试视图的挂载通常更方便,前提是不需要无状态 HTTP 渲染的结果。这可以通过对 live/2 进行一次调用来完成,该调用会为我们执行 get 步骤

test "connected mount", %{conn: conn} do
  {:ok, _view, html} = live(conn, "/my-path")
  assert html =~ "<h1>My Connected View</h1>"
end

测试事件

浏览器可以通过 phx- 绑定向 LiveView 发送各种事件,这些事件将发送到 handle_event/3 回调。要测试浏览器发送的事件并断言事件的渲染副作用,请使用 render_* 函数

  • render_click/1 - 发送 phx-click 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_focus/2 - 发送 phx-focus 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_blur/1 - 发送 phx-blur 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_submit/1 - 发送表单 phx-submit 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_change/1 - 发送表单 phx-change 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_keydown/1 - 发送表单 phx-keydown 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_keyup/1 - 发送表单 phx-keyup 事件和值,返回 handle_event/3 回调的渲染结果。

  • render_hook/3 - 发送挂钩事件和值,返回 handle_event/3 回调的渲染结果。

例如

{:ok, view, _html} = live(conn, "/thermo")

assert view
       |> element("button#inc")
       |> render_click() =~ "The temperature is: 31℉"

在上面的示例中,正在查找页面上的特定元素并触发其 phx-click 事件。LiveView 负责确保元素具有 phx-click 并自动将其值发送到服务器。

也可以绕过元素查找,并在大多数函数中直接触发 LiveView 事件

assert render_click(view, :inc, %{}) =~ "The temperature is: 31℉"

element 样式尽可能优先使用,因为它有助于 LiveView 执行验证并确保 HTML 中的事件实际与服务器上的事件名称匹配。

测试常规消息

LiveView 在幕后是 GenServer,可以像其他任何服务器一样发送和接收消息。要测试发送或接收消息的副作用,只需向视图发送消息并使用 render 函数来测试结果即可

send(view.pid, {:set_temp, 50})
assert render(view) =~ "The temperature is: 50℉"

测试 LiveComponent

LiveComponent 可以通过两种方式进行测试。一种方法是使用与函数组件相同的 render_component/2 函数。这将挂载 LiveComponent 并渲染一次,而不会测试任何事件

assert render_component(MyComponent, id: 123, user: %User{}) =~
         "some markup in component"

但是,如果要测试组件如何由 LiveView 挂载并与 DOM 事件交互,必须使用常规的 live/2 宏来构建包含组件的 LiveView,然后通过将视图和 **DOM 选择器** 传递到列表中来限定事件范围

{:ok, view, html} = live(conn, "/users")
html = view |> element("#user-13 a", "Delete") |> render_click()
refute html =~ "user-13"
refute view |> element("#user-13") |> has_element?()

在上面的示例中,LiveView 将查找具有 ID=user-13 的元素并检索其 phx-target。如果 phx-target 指向组件,则将使用该组件,否则将回退到视图。

总结

函数

断言在 timeout 毫秒内将发生实时修补。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

断言在 timeout 毫秒内将发生到给定路径的实时修补。

断言执行了实时修补,并返回新的路径。

断言在 timeout 内将推送事件。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

断言在 timeout 毫秒内将发生重定向。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

断言在 timeout 毫秒内将发生到给定路径的重定向。

断言执行了重定向。

返回一个元素来限定函数的范围。

为测试表单中的上传构建文件输入。

parent LiveView 获取嵌套的 LiveView 子项,该子项的 child_id

render_* 操作或 {:error, redirect} 元组中跟随重定向。

接收 form_element 并断言 phx-trigger-action 已设置为 true,然后继续该请求。

返回一个表单元素来限定函数的范围。

检查页面上是否存在给定元素。

检查 view 上是否存在具有 text_filter 的给定 selector

生成连接的 LiveView 进程。

返回 parent LiveView 的当前 LiveView 子项列表。

生成连接的 LiveView 进程,该进程作为唯一渲染的元素在隔离状态下挂载。

从一个 LiveView 执行到另一个 LiveView 的实时重定向。

打开默认浏览器以显示 view_or_element 的当前 HTML。

返回最近通过 page_title 分配更新的标题。

执行预检上传请求。

放置将在 LiveView 连接上使用的连接参数。

在给定的 form 元素上放置提交者 element_or_selector

反驳到给定路径的重定向是否已执行。

返回渲染的视图或元素的 HTML 字符串。

等待给定 LiveView 或元素的所有当前 assign_asyncstart_async

发送由 element 给出的模糊事件并返回渲染结果。

向视图发送模糊事件并返回渲染结果。

发送由 element 给出的表单更改事件并返回渲染结果。

向视图发送表单更改事件并返回渲染结果。

发送由 element 给出的点击事件并返回渲染结果。

view 发送点击 event,并使用 value 返回渲染结果。

发送由 element 给出的聚焦事件并返回渲染结果。

向视图发送聚焦事件并返回渲染结果。

向视图或元素发送挂钩事件并返回渲染结果。

发送由 element 给出的键按下事件并返回渲染结果。

向视图发送键按下事件并返回渲染结果。

发送由 element 给定的键盘弹起事件,并返回渲染结果。

向视图发送键盘弹起事件,并返回渲染结果。

模拟到给定 pathlive_patch,并返回渲染结果。

发送由 element 给定的表单提交事件,并返回渲染结果。

向视图发送表单提交事件,并返回渲染结果。

执行文件输入的上传并渲染结果。

将渲染的模板转换为字符串。

接收表单元素,并通过插头管道提交 HTTP 请求。

为事件设置视图的目标。

函数

链接到此函数

assert_patch(view, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout))

查看源代码

断言在 timeout 毫秒内将发生实时修补。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

它返回新的路径。

要断言闪存消息,你可以在渲染的 LiveView 的结果上断言。

例子

render_click(view, :event_that_triggers_patch)
assert_patch view

render_click(view, :event_that_triggers_patch)
assert_patch view, 30

render_click(view, :event_that_triggers_patch)
path = assert_patch view
assert path =~ ~r/path/+/
链接到此函数

assert_patch(view, to, timeout)

查看源代码

断言在 timeout 毫秒内将发生到给定路径的实时修补。

默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

它返回新的路径。

要断言闪存消息,你可以在渲染的 LiveView 的结果上断言。

例子

render_click(view, :event_that_triggers_patch)
assert_patch view, "/path"

render_click(view, :event_that_triggers_patch)
assert_patch view, "/path", 30
链接到此函数

assert_patched(view, to)

查看源代码

断言执行了实时修补,并返回新的路径。

要断言闪存消息,你可以在渲染的 LiveView 的结果上断言。

例子

render_click(view, :event_that_triggers_redirect)
assert_patched view, "/path"
链接到此宏

assert_push_event(view, event, payload, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout))

查看源代码 (宏)

断言在 timeout 内将推送事件。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

例子

assert_push_event view, "scores", %{points: 100, user: "josé"}
链接到此函数

assert_redirect(view, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout))

查看源代码

断言在 timeout 毫秒内将发生重定向。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

它返回一个元组,其中包含新的路径和来自该重定向的闪存消息(如果有)。请注意,闪存将包含字符串键。

例子

render_click(view, :event_that_triggers_redirect)
{path, flash} = assert_redirect view
assert flash["info"] == "Welcome"
assert path =~ ~r/path\/\d+/

render_click(view, :event_that_triggers_redirect)
assert_redirect view, 30
链接到此函数

assert_redirect(view, to, timeout)

查看源代码

断言在 timeout 毫秒内将发生到给定路径的重定向。

默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

它返回来自该重定向的闪存消息(如果有)。请注意,闪存将包含字符串键。

例子

render_click(view, :event_that_triggers_redirect)
flash = assert_redirect view, "/path"
assert flash["info"] == "Welcome"

render_click(view, :event_that_triggers_redirect)
assert_redirect view, "/path", 30
链接到此函数

assert_redirected(view, to)

查看源代码

断言执行了重定向。

它返回来自该重定向的闪存消息(如果有)。请注意,闪存将包含字符串键。

例子

render_click(view, :event_that_triggers_redirect)
flash = assert_redirected view, "/path"
assert flash["info"] == "Welcome"
链接到此宏

assert_reply(view, payload, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout))

查看源代码 (宏)

断言从 handle_event 回调返回了挂钩回复。

默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

例子

assert_reply view, %{result: "ok", transaction_id: _}
链接到此函数

element(view, selector, text_filter \\ nil)

查看源代码

返回一个元素来限定函数的范围。

它期望当前 LiveView、一个查询选择器和一个文本过滤器。

可以给出可选的文本过滤器来根据查询选择器过滤结果。如果文本过滤器是字符串或正则表达式,它将匹配包含该字符串(包括作为子字符串)或匹配正则表达式的任何元素。

因此,包含文本“unopened”的链接将匹配 element("a", "opened")。要阻止这种情况,正则表达式可以指定“opened”在没有前缀“un”的情况下出现。例如,element("a", ~r{(?<!un)opened})。但是,为元素添加 HTML 属性以使其更容易选择可能会更清楚。

应用文本过滤器后,必须只保留一个元素,否则会引发错误。

如果没有给出文本过滤器,则查询选择器本身必须返回单个元素。

assert view
      |> element("#term > :first-child", "Increment")
      |> render() =~ "Increment</a>"

属性选择器也受支持,并且可以在特殊情况下使用,例如包含句点的 id

assert view
       |> element(~s{[href="/foo"][id="foo.bar.baz"]})
       |> render() =~ "Increment</a>"
链接到此宏

file_input(view, form_selector, name, entries)

查看源代码 (宏)

为测试表单中的上传构建文件输入。

给定表单 DOM 选择器、上传名称和上传的客户端元数据的映射列表,返回的文件输入可以传递给 render_upload/2

客户端元数据采用以下形式

  • :last_modified - 最后修改时间戳
  • :name - 文件的名称
  • :content - 文件的二进制内容
  • :size - 内容的字节大小
  • :type - 文件的 MIME 类型
  • :relative_path - 用于模拟 webkitdirectory 元数据
  • :meta - 客户端发送的可选元数据

例子

avatar = file_input(lv, "#my-form-id", :avatar, [%{
  last_modified: 1_594_171_879_000,
  name: "myfile.jpeg",
  content: File.read!("myfile.jpg"),
  size: 1_396_009,
  type: "image/jpeg"
}])

assert render_upload(avatar, "myfile.jpeg") =~ "100%"
链接到此函数

find_live_child(parent, child_id)

查看源代码

parent LiveView 获取嵌套的 LiveView 子项,该子项的 child_id

例子

{:ok, view, _html} = live(conn, "/thermo")
assert clock_view = find_live_child(view, "clock")
assert render_click(clock_view, :snooze) =~ "snoozing"
链接到此宏

follow_redirect(reason, conn, to \\ nil)

查看源代码 (宏)

render_* 操作或 {:error, redirect} 元组中跟随重定向。

假设你有一个在 render_click 事件上重定向的 LiveView。你可以通过调用 follow_redirect/3 来确保它在 render_click 操作后立即重定向

live_view
|> render_click("redirect")
|> follow_redirect(conn)

或者在错误元组的情况下

assert {:error, {:redirect, %{to: "/somewhere"}}} = result = live(conn, "my-path")
{:ok, view, html} = follow_redirect(result, conn)

follow_redirect/3 期望连接作为第二个参数。这是将用于执行底层请求的连接。

如果 LiveView 使用实时重定向进行重定向,此宏将返回 {:ok, live_view, disconnected_html},其中包含新 LiveView 的内容,与 live/3 宏相同。如果 LiveView 使用常规重定向进行重定向,则此宏将返回 {:ok, conn},其中包含渲染的重定向页面。在任何其他情况下,此宏都会引发异常。

最后,请注意,你可以通过传递第三个参数来可选地断言你正在被重定向到的路径

live_view
|> render_click("redirect")
|> follow_redirect(conn, "/redirected/page")
链接到此宏

follow_trigger_action(form, conn)

查看源代码 (宏)

接收 form_element 并断言 phx-trigger-action 已设置为 true,然后继续该请求。

假设你有一个发送 HTTP 表单提交的 LiveView。假设它将 phx-trigger-action 设置为 true,作为对提交事件的响应。你可以像这样跟踪触发操作

form = form(live_view, selector, %{"form" => "data"})

# First we submit the form. Optionally verify that phx-trigger-action
# is now part of the form.
assert render_submit(form) =~ ~r/phx-trigger-action/

# Now follow the request made by the form
conn = follow_trigger_action(form, conn)
assert conn.method == "POST"
assert conn.params == %{"form" => "data"}
链接到此函数

form(view, selector, form_data \\ %{})

查看源代码

返回一个表单元素来限定函数的范围。

它期望当前 LiveView、一个查询选择器和表单数据。查询选择器必须返回单个元素。

表单数据将直接针对表单标记进行验证,并确保你正在更改/提交的数据确实存在,否则会失败。

例子

assert view
      |> form("#term", user: %{name: "hello"})
      |> render_submit() =~ "Name updated"

此函数旨在模仿用户可以实际执行的操作,因此你无法设置隐藏的输入值。但是,在调用 render_submit/2render_change/2 时可以给出隐藏的值,请参阅其文档以获取示例。

检查页面上是否存在给定元素。

例子

assert view |> element("#some-element") |> has_element?()
链接到此函数

has_element?(view, selector, text_filter \\ nil)

查看源代码

检查 view 上是否存在具有 text_filter 的给定 selector

请参阅 element/3 以获取更多信息。

例子

assert has_element?(view, "#some-element")
链接到此宏

live(conn, path \\ nil)

查看源代码 (宏)

生成连接的 LiveView 进程。

如果给出了 path,则会执行常规的 get(conn, path),并且页面将升级为 LiveView。如果没有给出路径,它假定给出了先前渲染的 %Plug.Conn{},该连接将立即转换为 LiveView。

例子

{:ok, view, html} = live(conn, "/path")
assert view.module == MyLive
assert html =~ "the count is 3"

assert {:error, {:redirect, %{to: "/somewhere"}}} = live(conn, "/path")

返回 parent LiveView 的当前 LiveView 子项列表。

子元素按它们在渲染的 HTML 中出现的顺序返回。

例子

{:ok, view, _html} = live(conn, "/thermo")
assert [clock_view] = live_children(view)
assert render_click(clock_view, :snooze) =~ "snoozing"
链接到此宏

live_isolated(conn, live_view, opts \\ [])

查看源代码 (宏)

生成连接的 LiveView 进程,该进程作为唯一渲染的元素在隔离状态下挂载。

对于测试不可直接路由的 LiveView 很有用,例如那些作为小组件构建以在多个父级中重复使用的 LiveView。无论何时可能,都建议测试可路由的 LiveView,因为诸如实时导航之类的功能需要可路由的 LiveView。

选项

  • :session - 将提供给 LiveView 的会话

所有其他选项都转发到 LiveView 以进行渲染。有关支持的渲染选项列表,请参阅 Phoenix.Component.live_render/3

例子

{:ok, view, html} =
  live_isolated(conn, MyAppWeb.ClockLive, session: %{"tz" => "EST"})

使用 put_connect_params/2Phoenix.LiveView.get_connect_params/1Phoenix.LiveView.mount/3 中的调用添加连接参数。

{:ok, view, html} =
  conn
  |> put_connect_params(%{"param" => "value"})
  |> live_isolated(AppWeb.ClockLive, session: %{"tz" => "EST"})
链接到此函数

live_redirect(view, opts)

查看源代码

从一个 LiveView 执行到另一个 LiveView 的实时重定向。

在具有相同 live_session 的两个 LiveView 之间重定向时,它会安装新的 LiveView 并关闭先前的 LiveView,这模拟了常规的浏览器实时导航行为。

尝试从具有不同 live_session 的 LiveView 导航时,会返回一个错误重定向条件,表明客户端的 live_redirect 失败。

例子

assert {:ok, page_live, _html} = live(conn, "/page/1")
assert {:ok, page2_live, _html} = live(conn, "/page/2")

assert {:error, {:redirect, _}} = live_redirect(page2_live, to: "/admin")
链接到此函数

open_browser(view_or_element, open_fun \\ &open_with_system_cmd/1)

查看源代码

打开默认浏览器以显示 view_or_element 的当前 HTML。

例子

view
|> element("#term > :first-child", "Increment")
|> open_browser()

assert view
       |> form("#term", user: %{name: "hello"})
       |> open_browser()
       |> render_submit() =~ "Name updated"

返回最近通过 page_title 分配更新的标题。

例子

render_click(view, :event_that_triggers_page_title_update)
assert page_title(view) =~ "my title"
链接到此函数

preflight_upload(upload)

查看源代码

执行预检上传请求。

对于测试外部上传器以检索 :external 条目元数据很有用。

例子

avatar = file_input(lv, "#my-form-id", :avatar, [%{name: ..., ...}, ...])
assert {:ok, %{ref: _ref, config: %{chunk_size: _}}} = preflight_upload(avatar)
链接到此函数

put_connect_params(conn, params)

查看源代码

放置将在 LiveView 连接上使用的连接参数。

请参阅 Phoenix.LiveView.get_connect_params/1

链接到此函数

put_submitter(form, element_or_selector)

查看源代码

在给定的 form 元素上放置提交者 element_or_selector

提交者是启动客户端上表单提交事件的元素。当提交者被放在使用 form/3 创建的元素上,然后表单通过 render_submit/2 提交时,提交者的名称/值对将包含在提交事件有效负载中。

给定的元素或选择器必须存在于表单中,并且必须匹配以下之一

  • 具有 type="submit"buttoninput 元素。

  • 没有 type 属性的 button 元素。

例子

form = view |> form("#my-form")

assert form
       |> put_submitter("button[name=example]")
       |> render_submit() =~ "Submitted example"
链接到此函数

refute_redirected(view, to)

查看源代码

反驳到给定路径的重定向是否已执行。

如果指定的重定向不在邮箱中,它将返回 :ok。

例子

render_click(view, :event_that_triggers_redirect_to_path)
:ok = refute_redirected view, "/wrong_path"
链接到此函数

render(view_or_element)

查看源代码

返回渲染的视图或元素的 HTML 字符串。

如果提供了视图,则将渲染整个 LiveView。如果给出了调用 with_target/2 后的视图或元素,则只返回该特定上下文。

例子

{:ok, view, _html} = live(conn, "/thermo")
assert render(view) =~ ~s|<button id="alarm">Snooze</div>|

assert view
       |> element("#alarm")
       |> render() == "Snooze"
链接到此函数

render_async(view_or_element, timeout \\ Application.fetch_env!(:ex_unit, :assert_receive_timeout))

查看源代码

等待给定 LiveView 或元素的所有当前 assign_asyncstart_async

它在完成时渲染 LiveView 或元素,并返回结果。默认的 timeoutExUnitassert_receive_timeout(100 毫秒)。

示例

{:ok, lv, html} = live(conn, "/path")
assert html =~ "loading data..."
assert render_async(lv) =~ "data loaded!"
链接到此函数

render_blur(element, value \\ %{})

查看源代码

发送由 element 给出的模糊事件并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-blur attribute in it. The event name given set on phx-blur is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values can be given with the value argument.

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("#inactive")
       |> render_blur() =~ "Tap to wake"
链接到此函数

render_blur(view, event, value)

查看源代码

向视图发送模糊事件并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_blur(view, :inactive) =~ "Tap to wake"
链接到此函数

render_change(element, value \\ %{})

查看源代码

发送由 element 给出的表单更改事件并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-change attribute in it. The event name given set on phx-change is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values.

如果您需要传递任何额外的值或元数据,例如 “_target” 参数,您可以通过在 value 参数下提供一个映射来实现。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("form")
       |> render_change(%{deg: 123}) =~ "123 exceeds limits"

# Passing metadata
{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("form")
       |> render_change(%{_target: ["deg"], deg: 123}) =~ "123 exceeds limits"

render_submit/2 一样,隐藏的输入字段值可以像这样提供

refute view
      |> form("#term", user: %{name: "hello"})
      |> render_change(%{user: %{"hidden_field" => "example"}}) =~ "can't be blank"
链接到此函数

render_change(view, event, value)

查看源代码

向视图发送表单更改事件并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_change(view, :validate, %{deg: 123}) =~ "123 exceeds limits"
链接到此函数

render_click(element, value \\ %{})

查看源代码

发送由 element 给出的点击事件并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-click attribute in it. The event name given set on phx-click is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values can be given with the value argument.

如果元素没有 phx-click 属性,但它是一个链接(<a> 标签),则会相应地跟随该链接

  • 如果链接是 live_patch,当前视图将被修补
  • 如果链接是 live_redirect,此函数将返回 {:error, {:live_redirect, %{to: url}}},可以使用 follow_redirect/2 跟踪它
  • 如果链接是常规链接,此函数将返回 {:error, {:redirect, %{to: url}}},可以使用 follow_redirect/2 跟踪它

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("button", "Increment")
       |> render_click() =~ "The temperature is: 30℉"
链接到此函数

render_click(view, event, value)

查看源代码

view 发送点击 event,并使用 value 返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temperature is: 30℉"
assert render_click(view, :inc) =~ "The temperature is: 31℉"
链接到此宏

render_component(component, assigns \\ Macro.escape(%{}), opts \\ [])

查看源代码 (宏)

渲染组件。

第一个参数可以是一个函数组件,作为一个匿名函数

assert render_component(&Weather.city/1, name: "Kraków") =~
         "some markup in component"

或者一个有状态的组件,作为一个模块。在这种情况下,此函数将挂载、更新和渲染组件。 :id 选项是必需的参数

assert render_component(MyComponent, id: 123, user: %User{}) =~
         "some markup in component"

如果您的组件正在使用路由器,您可以将它作为参数传递

assert render_component(MyComponent, %{id: 123, user: %User{}}, router: SomeRouter) =~
         "some markup in component"
链接到此函数

render_focus(element, value \\ %{})

查看源代码

发送由 element 给出的聚焦事件并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-focus attribute in it. The event name given set on phx-focus is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values can be given with the value argument.

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("#inactive")
       |> render_focus() =~ "Tap to wake"
链接到此函数

render_focus(view, event, value)

查看源代码

向视图发送聚焦事件并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_focus(view, :inactive) =~ "Tap to wake"
链接到此函数

render_hook(view_or_element, event, value \\ %{})

查看源代码

向视图或元素发送挂钩事件并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_hook(view, :refresh, %{deg: 32}) =~ "The temp is: 32℉"

如果您从钩子将事件推送到组件,那么您必须传递一个 element(使用 element/3 创建),作为第一个参数,它必须指向页面上具有 phx-target 属性的单个元素

{:ok, view, _html} = live(conn, "/thermo")
assert view
       |> element("#thermo-component")
       |> render_hook(:refresh, %{deg: 32}) =~ "The temp is: 32℉"
链接到此函数

render_keydown(element, value \\ %{})

查看源代码

发送由 element 给出的键按下事件并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-keydown or phx-window-keydown attribute in it. The event name given set on phx-keydown is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values can be given with the value argument.

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert view |> element("#inc") |> render_keydown() =~ "The temp is: 31℉"
链接到此函数

render_keydown(view, event, value)

查看源代码

向视图发送键按下事件并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_keydown(view, :inc) =~ "The temp is: 31℉"
链接到此函数

render_keyup(element, value \\ %{})

查看源代码

发送由 element 给定的键盘弹起事件,并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-keyup or phx-window-keyup attribute in it. The event name given set on phx-keyup is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values can be given with the value argument.

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert view |> element("#inc") |> render_keyup() =~ "The temp is: 31℉"
链接到此函数

render_keyup(view, event, value)

查看源代码

向视图发送键盘弹起事件,并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_keyup(view, :inc) =~ "The temp is: 31℉"
链接到此函数

render_patch(view, path)

查看源代码

模拟到给定 pathlive_patch,并返回渲染结果。

链接到此函数

render_submit(element, value \\ %{})

查看源代码

发送由 element 给定的表单提交事件,并返回渲染结果。

The element is created with element/3 and must point to a single element on the page with a phx-submit attribute in it. The event name given set on phx-submit is then sent to the appropriate LiveView (or component if phx-target is set accordingly). All phx-value-* entries in the element are sent as values. Extra values, including hidden input fields, can be given with the value argument.

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")

assert view
       |> element("form")
       |> render_submit(%{deg: 123, avatar: upload}) =~ "123 exceeds limits"

要提交包含一些隐藏输入值的表单

assert view
       |> form("#term", user: %{name: "hello"})
       |> render_submit(%{user: %{"hidden_field" => "example"}}) =~ "Name updated"

要通过 put_submitter/2 通过特定提交元素提交表单

assert view
       |> form("#term", user: %{name: "hello"})
       |> put_submitter("button[name=example_action]")
       |> render_submit() =~ "Action taken"
链接到此函数

render_submit(view, event, value)

查看源代码

向视图发送表单提交事件,并返回渲染结果。

它返回整个 LiveView 的内容或一个 {:error, redirect} 元组。

示例

{:ok, view, html} = live(conn, "/thermo")
assert html =~ "The temp is: 30℉"
assert render_submit(view, :refresh, %{deg: 32}) =~ "The temp is: 32℉"
链接到此函数

render_upload(upload, entry_name, percent \\ 100)

查看源代码

执行文件输入的上传并渲染结果。

有关构建文件输入的详细信息,请参阅 file_input/4

示例

给定以下 LiveView 模板

<%= for entry <- @uploads.avatar.entries do %>
    <%= entry.name %>: <%= entry.progress %>%
<% end %>

您的测试用例可以断言上传的内容

avatar = file_input(lv, "#my-form-id", :avatar, [
  %{
    last_modified: 1_594_171_879_000,
    name: "myfile.jpeg",
    content: File.read!("myfile.jpg"),
    size: 1_396_009,
    type: "image/jpeg"
  }
])

assert render_upload(avatar, "myfile.jpeg") =~ "100%"

默认情况下,整个文件被分成块并发送到服务器,但您可以传递一个可选的百分比以分块进行测试,以逐块上传

assert render_upload(avatar, "myfile.jpeg", 49) =~ "49%"
assert render_upload(avatar, "myfile.jpeg", 51) =~ "100%"

在对上传如何在服务器端被消耗进行断言之前,您需要调用 render_submit/1

在上传进度回调发出导航、修补或重定向的情况下,将返回以下内容

  • 如果导航是 live_patch,当前视图将被修补
  • 如果导航是 live_redirect,此函数将返回 {:error, {:live_redirect, %{to: url}}},可以使用 follow_redirect/2 跟踪它
  • 如果导航是常规重定向,此函数将返回 {:error, {:redirect, %{to: url}}},可以使用 follow_redirect/2 跟踪它
链接到此函数

rendered_to_string(rendered)

查看源代码

将渲染的模板转换为字符串。

示例

import Phoenix.Component
import Phoenix.LiveViewTest

test "greets" do
  assigns = %{}
  assert rendered_to_string(~H"""
         <MyComponents.greet name="Mary" />
         """) ==
           "<div>Hello, Mary!</div>"
end
链接到此宏

submit_form(form, conn)

查看源代码 (宏)

接收表单元素,并通过插头管道提交 HTTP 请求。

假设您有一个 LiveView 可以验证表单数据,但通过常规表单 action 属性将表单提交到控制器。这在表单提交结果需要写入插件会话的场景中特别有用。

您可以使用 %Plug.Conn{} 提交表单,如下所示

form = form(live_view, selector, %{"form" => "data"})

# Now submit the LiveView form to the plug pipeline
conn = submit_form(form, conn)
assert conn.method == "POST"
assert conn.params == %{"form" => "data"}
链接到此函数

with_target(view, target)

查看源代码

为事件设置视图的目标。

这在测试中直接模拟了 phx-target,无需将事件分派到特定元素。这对于同时调用一个或多个组件的事件很有用

view
|> with_target("#user-1,#user-2")
|> render_click("Hide", %{})