defmodule Pages.Driver do
# @related [conn driver](lib/pages/driver/conn.ex)
# @related [live view driver](lib/pages/driver/live_view.ex)
@moduledoc """
Defines types and behaviours that page drivers must implement.
"""
alias HtmlQuery, as: Hq
@type t() ::
Pages.Driver.Conn.t()
| Pages.Driver.LiveView.t()
@doc "Click an element within a page. Implementation for `Pages.click/4`."
@callback click(Pages.Driver.t(), Pages.http_method(), Pages.text_filter() | nil, Hq.Css.selector()) ::
Pages.result() | no_return()
@doc "Render a change. Implementation for `Pages.render_change/3`."
@callback render_change(Pages.Driver.t(), Hq.Css.selector(), Enum.t()) :: Pages.result()
@doc "Render a file upload. Implementation for `Pages.render_upload/4`."
@callback render_upload(Pages.Driver.t(), Pages.live_view_upload(), binary(), integer()) :: Pages.result()
@doc "Render a hook event. Implementation for `Pages.render_hook/3`."
@callback render_hook(Pages.Driver.t(), binary(), Pages.attrs_t(), keyword()) :: Pages.result()
@doc "Re-renders the page. Implementation for `Pages.rerender/1`."
@callback rerender(Pages.Driver.t()) :: Pages.result()
@doc "Submit a form targeted by the given selector. Implementation for `Pages.submit_form/2`."
@callback submit_form(Pages.Driver.t(), Hq.Css.selector()) :: Pages.result()
@doc "Fills in a form with the attributes and submits it. Implementation for `Pages.submit_form/4`."
@callback submit_form(Pages.Driver.t(), Hq.Css.selector(), atom(), Pages.attrs_t()) :: Pages.result()
@doc "Fills in a form with the attributes and submits it. Implementation for `Pages.submit_form/5`."
@callback submit_form(Pages.Driver.t(), Hq.Css.selector(), atom(), Pages.attrs_t(), Pages.attrs_t()) ::
Pages.result()
@doc "Fills in a form with the attributes without submitting it. Implementation for `Pages.update_form/4`."
@callback update_form(Pages.Driver.t(), Hq.Css.selector(), atom(), Pages.attrs_t()) :: Pages.result()
@doc "Navigate directly to a page. Implementation for `Pages.visit/2`."
@callback visit(Pages.Driver.t(), Path.t()) :: Pages.result()
@doc "Target a child component for actions. Implementation for `Pages.with_child_component/3`."
@callback with_child_component(Pages.Driver.t(), child_id :: binary(), (Pages.Driver.t() -> term())) ::
Pages.Driver.t()
@optional_callbacks [
click: 4,
render_change: 3,
render_upload: 4,
render_hook: 4,
rerender: 1,
submit_form: 2,
submit_form: 4,
submit_form: 5,
update_form: 4,
with_child_component: 3
]
end