Current section

Files

Jump to
playwright lib playwright runner channel callback.ex
Raw

lib/playwright/runner/channel/callback.ex

defmodule Playwright.Runner.Channel.Callback do
@moduledoc false
require Logger
alias Playwright.ElementHandle
alias Playwright.Runner.Channel
alias Playwright.Runner.Channel.Callback
alias Playwright.Runner.Channel.Error
alias Playwright.Runner.Channel.Response
defstruct [:listener, :message]
def new(listener, message) do
%__MODULE__{
listener: listener,
message: message
}
end
def resolve(%Callback{listener: listener}, %Error{} = error) do
GenServer.reply(listener, {:error, error})
end
def resolve(%Callback{listener: listener}, %Response{parsed: %ElementHandle{} = handle}) do
Task.start_link(fn ->
GenServer.reply(listener, await_preview(handle))
end)
end
def resolve(%Callback{listener: listener}, %Response{parsed: parsed})
when is_list(parsed) do
Task.start_link(fn ->
GenServer.reply(listener, await_preview(parsed))
end)
end
def resolve(%Callback{listener: listener}, %Response{parsed: parsed}) do
GenServer.reply(listener, {:ok, parsed})
end
# private
# ---------------------------------------------------------------------------
defp await_preview(handle, timeout \\ DateTime.utc_now() |> DateTime.add(5, :second))
defp await_preview(items, timeout) when is_list(items) do
result =
Enum.map(items, fn item ->
{:ok, item} = await_preview(item, timeout)
item
end)
{:ok, result}
end
defp await_preview(%ElementHandle{} = handle, timeout) do
if DateTime.compare(DateTime.utc_now(), timeout) == :gt do
# {:error, :timeout}
# hmm... maybe it's OK in most cases that the preview is not "hydrated" (?)
Logger.warn("Timed out awaiting preview update... returning handle as is: #{inspect(handle)}")
{:ok, handle}
else
case handle.preview do
"JSHandle@node" ->
:timer.sleep(5)
Channel.find(handle) |> await_preview(timeout)
_hydrated ->
{:ok, handle}
end
end
end
defp await_preview(item, _timeout) do
{:ok, item}
end
end