Skip to content

Commit

Permalink
[Changed] API/SDK rebuild (3/n)
Browse files Browse the repository at this point in the history
Rehomed `Playwright.Channel` into `Playwright.SDK`.
  • Loading branch information
coreyti committed May 20, 2024
1 parent ced32fe commit 4cb79ef
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 34 deletions.
4 changes: 2 additions & 2 deletions lib/playwright.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ defmodule Playwright do

defp new_browser(session, client, options)
when is_atom(client) and client in [:chromium, :firefox, :webkit] do
with play <- Playwright.Channel.find(session, {:guid, "Playwright"}),
with play <- Playwright.SDK.Channel.find(session, {:guid, "Playwright"}),
guid <- Map.get(play, client)[:guid] do
{:ok, Playwright.Channel.post(session, {:guid, guid}, :launch, options)}
{:ok, Playwright.SDK.Channel.post(session, {:guid, guid}, :launch, options)}
end
end

Expand Down
7 changes: 4 additions & 3 deletions lib/playwright/browser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ defmodule Playwright.Browser do
- `:version`
"""
use Playwright.SDK.ChannelOwner
alias Playwright.{Browser, BrowserContext, ChannelOwner, Extra, Page}
alias Playwright.Channel
alias Playwright.{Browser, BrowserContext, Extra, Page}
alias Playwright.Channel.Error
alias Playwright.SDK.{Channel, ChannelOwner}

@property :name
@property(:version, %{doc: "Returns the browser version"})
Expand Down Expand Up @@ -66,7 +67,7 @@ defmodule Playwright.Browser do
:ok ->
:ok

{:error, %Channel.Error{message: "Target page, context or browser has been closed"}} ->
{:error, %Error{message: "Target page, context or browser has been closed"}} ->
:ok
end
end
Expand Down
8 changes: 5 additions & 3 deletions lib/playwright/browser_context.ex
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ defmodule Playwright.BrowserContext do
"""

use Playwright.SDK.ChannelOwner
alias Playwright.{BrowserContext, ChannelOwner, Frame, Page}
alias Playwright.{Channel, Helpers}
alias Playwright.{BrowserContext, Frame, Page}
alias Playwright.Channel.Error
alias Playwright.Helpers
alias Playwright.SDK.{Channel, ChannelOwner}

@property :bindings
@property :browser
Expand Down Expand Up @@ -342,7 +344,7 @@ defmodule Playwright.BrowserContext do
:ok ->
:ok

{:error, %Channel.Error{message: "Target page, context or browser has been closed"}} ->
{:error, %Error{message: "Target page, context or browser has been closed"}} ->
:ok
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/cdp_session.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
defmodule Playwright.CDPSession do
@moduledoc false
use Playwright.SDK.ChannelOwner
alias Playwright.{CDPSession, ChannelOwner}
alias Playwright.CDPSession
alias Playwright.SDK.ChannelOwner

@property :bindings

Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/channel/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule Playwright.Channel.Connection do
@moduledoc false
use GenServer
require Logger
alias Playwright.{Channel, Extra, Transport}
alias Playwright.{Extra, Transport}
alias Playwright.SDK.Channel

defstruct(
callbacks: %{},
Expand Down
2 changes: 1 addition & 1 deletion lib/playwright/channel/response.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Playwright.Channel.Response do
@moduledoc false
alias Playwright.SDK.ChannelOwner
alias Playwright.Channel.{Catalog, Error, Event, Session}
alias Playwright.SDK.ChannelOwner

defstruct [:message, :parsed]

Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/element_handle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ defmodule Playwright.ElementHandle do
"""

use Playwright.SDK.ChannelOwner
alias Playwright.{Channel, ChannelOwner, ElementHandle, Frame, JSHandle}
alias Playwright.{ElementHandle, Frame, JSHandle}
alias Playwright.SDK.{Channel, ChannelOwner}

@property :preview

Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/frame.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ defmodule Playwright.Frame do
"""
use Playwright.SDK.ChannelOwner
alias Playwright.Channel.Event
alias Playwright.{ChannelOwner, ElementHandle, Frame, Helpers, Response}
alias Playwright.{ElementHandle, Frame, Helpers, Response}
alias Playwright.SDK.ChannelOwner

@property :load_states
@property :url
Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/locator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ defmodule Playwright.Locator do
Locator.count(locator)
"""

alias Playwright.{Channel, ElementHandle, Frame, Locator, Page}
alias Playwright.{ElementHandle, Frame, Locator, Page}
alias Playwright.SDK.Channel

@enforce_keys [:frame, :selector]
defstruct [:frame, :selector]
Expand Down
3 changes: 2 additions & 1 deletion lib/playwright/page/accessibility.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ defmodule Playwright.Page.Accessibility do
[2]: https://en.wikipedia.org/wiki/Switch_access
"""

alias Playwright.{Channel, ElementHandle, Extra, Page}
alias Playwright.{ElementHandle, Extra, Page}
alias Playwright.SDK.Channel

@typedoc """
Options given to `snapshot/2`
Expand Down
146 changes: 146 additions & 0 deletions lib/playwright/sdk/channel.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
defmodule Playwright.SDK.Channel do
@moduledoc false
import Playwright.Helpers.ErrorHandling
alias Playwright.Channel.{Catalog, Connection, Error, Event, Message, Response, Session}

# API
# ---------------------------------------------------------------------------

def bind(session, {:guid, guid}, event_type, callback) when is_binary(guid) do
Session.bind(session, {guid, event_type}, callback)
end

def find(session, {:guid, guid}, options \\ %{}) when is_binary(guid) do
Session.catalog(session) |> Catalog.get(guid, options)
end

def list(session, {:guid, guid}, type) do
Catalog.list(Session.catalog(session), %{
parent: guid,
type: type
})
end

def patch(session, {:guid, guid}, data) when is_binary(guid) do
catalog = Session.catalog(session)
owner = Catalog.get(catalog, guid)
Catalog.put(catalog, Map.merge(owner, data))
end

def post(session, {:guid, guid}, message, params \\ %{}) when is_binary(guid) when is_pid(session) do
connection = Session.connection(session)
message = Message.new(guid, message, params)

with_timeout(params, fn timeout ->
case Connection.post(connection, message, timeout) do
{:ok, %{id: _}} -> :ok
{:ok, resource} -> resource
{:error, error} -> {:error, error}
end
end)
end

def recv(session, {nil, message}) when is_map(message) do
Response.recv(session, message)
end

def recv(session, {from, message}) when is_map(message) do
Response.recv(session, message)
|> reply(from)
end

# or, "expect"?
def wait(session, owner, event_type, options \\ %{}, trigger \\ nil)

def wait(session, {:guid, guid}, event_type, options, trigger) when is_map(options) do
connection = Session.connection(session)

with_timeout(options, fn timeout ->
{:ok, event} = Connection.wait(connection, {:guid, guid}, event_type, timeout, trigger)
evaluate(event, options)
end)
end

def wait(session, {:guid, guid}, event, trigger, _) when is_function(trigger) do
wait(session, {:guid, guid}, event, %{}, trigger)
end

# private
# ---------------------------------------------------------------------------

defp evaluate(%Event{} = event, options) do
predicate = Map.get(options, :predicate)

if predicate do
with_timeout(options, fn timeout ->
task =
Task.async(fn ->
evaluate(predicate, event.target, event)
end)

Task.await(task, timeout)
end)
else
event
end
end

defp evaluate(predicate, resource, event) do
case predicate.(resource, event) do
false ->
:timer.sleep(5)
evaluate(predicate, resource, event)

_ ->
event
end
end

defp load_preview(handle, timeout \\ DateTime.utc_now() |> DateTime.add(5, :second))

defp load_preview(items, timeout) when is_list(items) do
result =
Enum.map(items, fn item ->
load_preview(item, timeout)
end)

result
end

defp load_preview(%Playwright.ElementHandle{session: session} = handle, timeout) do
if DateTime.compare(DateTime.utc_now(), timeout) == :gt do
{:error, :timeout}
else
case handle.preview do
"JSHandle@node" ->
:timer.sleep(5)
find(session, {:guid, handle.guid}) |> load_preview(timeout)

_hydrated ->
handle
end
end
end

defp load_preview(item, _timeout) do
item
end

defp reply(%Error{} = error, from) do
Task.start_link(fn ->
GenServer.reply(from, {:error, error})
end)
end

defp reply(%Response{} = response, from) do
Task.start_link(fn ->
GenServer.reply(from, {:ok, load_preview(response.parsed)})
end)
end

defp reply(%Event{} = event, from) do
Task.start_link(fn ->
GenServer.reply(from, {:ok, event})
end)
end
end
4 changes: 2 additions & 2 deletions lib/playwright/sdk/channel_owner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ defmodule Playwright.SDK.ChannelOwner do
@derive {Inspect, only: [:guid] ++ @properties}

import Playwright.Extra.Map
alias Playwright.Channel
alias Playwright.Channel.Event
alias Playwright.SDK.Channel

defstruct @properties ++ [:session, :guid, :initializer, :listeners, :parent, :type]

Expand Down Expand Up @@ -130,7 +130,7 @@ defmodule Playwright.SDK.ChannelOwner do

defmodule Macros do
@moduledoc false
alias Playwright.Channel
alias Playwright.SDK.Channel

defmacro __using__(_args) do
Module.register_attribute(__CALLER__.module, :properties, accumulate: true)
Expand Down
13 changes: 7 additions & 6 deletions test/integration/locator_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
defmodule Playwright.LocatorTest do
use Playwright.TestCase, async: true

alias Playwright.{Channel, ElementHandle, Locator, Page}
alias Playwright.{ElementHandle, Locator, Page}
alias Playwright.Channel.Error

describe "Locator.all_inner_texts/1" do
test "...", %{page: page} do
Expand Down Expand Up @@ -58,7 +59,7 @@ defmodule Playwright.LocatorTest do
frame = Page.main_frame(page)

locator = Locator.new(frame, "input#bogus")
assert {:error, %Channel.Error{message: "Timeout 200ms exceeded."}} = Locator.check(locator, options)
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.check(locator, options)
end
end

Expand All @@ -83,7 +84,7 @@ defmodule Playwright.LocatorTest do
frame = Page.main_frame(page)

locator = Locator.new(frame, "a#bogus")
assert {:error, %Channel.Error{message: "Timeout 200ms exceeded."}} = Locator.click(locator, options)
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.click(locator, options)
end

test "clicking a button", %{assets: assets, page: page} do
Expand Down Expand Up @@ -255,7 +256,7 @@ defmodule Playwright.LocatorTest do
test "accepts `option: timeout` for expression evaluation", %{page: page} do
locator = Page.locator(page, ".missing")
options = %{timeout: 500}
errored = {:error, %Channel.Error{message: "Timeout 500ms exceeded."}}
errored = {:error, %Error{message: "Timeout 500ms exceeded."}}

page
|> Page.set_content("""
Expand All @@ -272,7 +273,7 @@ defmodule Playwright.LocatorTest do
test "accepts `option: timeout` without a `param: arg`", %{page: page} do
locator = Page.locator(page, ".missing")
options = %{timeout: 500}
errored = {:error, %Channel.Error{message: "Timeout 500ms exceeded."}}
errored = {:error, %Error{message: "Timeout 500ms exceeded."}}

page
|> Page.set_content("""
Expand Down Expand Up @@ -709,7 +710,7 @@ defmodule Playwright.LocatorTest do

test "returns a timeout error when unable to 'uncheck'", %{options: options, page: page} do
locator = Page.locator(page, "input#bogus")
assert {:error, %Channel.Error{message: "Timeout 200ms exceeded."}} = Locator.uncheck(locator, options)
assert {:error, %Error{message: "Timeout 200ms exceeded."}} = Locator.uncheck(locator, options)
end
end

Expand Down
5 changes: 3 additions & 2 deletions test/integration/navigation_test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule Playwright.NavigationTest do
use Playwright.TestCase, async: true
alias Playwright.{Channel, Page, Response}
alias Playwright.{Page, Response}
alias Playwright.Channel.Error

describe "Page.goto/2" do
test "works (and updates the page's URL)", %{assets: assets, page: page} do
Expand Down Expand Up @@ -51,7 +52,7 @@ defmodule Playwright.NavigationTest do
end

test "fails when navigating to bad URL", %{page: page} do
error = %Channel.Error{
error = %Error{
message: "Protocol error (Page.navigate): Cannot navigate to invalid URL"
}

Expand Down
10 changes: 5 additions & 5 deletions test/integration/page/expect_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Playwright.Page.NetworkTest do
use Playwright.TestCase, async: true
alias Playwright.{BrowserContext, Channel, Page, Response}
alias Playwright.Channel.Event
alias Playwright.{BrowserContext, Page, Response}
alias Playwright.Channel.{Error, Event}

describe "Page.expect_event/3 without a 'trigger" do
test "w/ an event", %{assets: assets, page: page} do
Expand Down Expand Up @@ -35,7 +35,7 @@ defmodule Playwright.Page.NetworkTest do
end

test "w/ an event and a timeout", %{page: page} do
{:error, %Channel.Error{message: message}} =
{:error, %Error{message: message}} =
Page.expect_event(page, :request_finished, %{
timeout: 200
})
Expand All @@ -60,7 +60,7 @@ defmodule Playwright.Page.NetworkTest do
test "w/ an event, a (falsy) predicate, and (incidentally) a timeout", %{assets: assets, page: page} do
Task.start(fn -> Page.goto(page, assets.empty) end)

{:error, %Channel.Error{message: message}} =
{:error, %Error{message: message}} =
Page.expect_event(page, :request_finished, %{
predicate: fn _, _ ->
false
Expand Down Expand Up @@ -107,7 +107,7 @@ defmodule Playwright.Page.NetworkTest do
end

test "w/ an event and a (falsy) predicate", %{assets: assets, page: page} do
{:error, %Channel.Error{message: message}} =
{:error, %Error{message: message}} =
Page.expect_event(
page,
:request_finished,
Expand Down
Loading

0 comments on commit 4cb79ef

Please sign in to comment.