From e280f58ab1829d64187246fbf08c0c2b2579eb2b Mon Sep 17 00:00:00 2001 From: Corey Innis Date: Thu, 3 Oct 2024 15:38:40 -0400 Subject: [PATCH] API: impl `APIRequestContext` & `APIResponse` pipe/bang functions --- lib/playwright/api_request.ex | 9 +- lib/playwright/api_request_context.ex | 49 ++++- lib/playwright/api_response.ex | 7 + mix.exs | 2 +- mix.lock | 22 +- test/api/api_request_context_test.exs | 284 ++++++++++++++++++++++---- 6 files changed, 320 insertions(+), 53 deletions(-) diff --git a/lib/playwright/api_request.ex b/lib/playwright/api_request.ex index 02b3d66..aff4f18 100644 --- a/lib/playwright/api_request.ex +++ b/lib/playwright/api_request.ex @@ -279,7 +279,14 @@ defmodule Playwright.APIRequest do @pipe {:new_context, [:request]} @pipe {:new_context, [:request, :options]} @spec new_context(t(), options()) :: APIRequestContext.t() | {:error, Error.t()} - def new_context(%APIRequest{} = request, options \\ %{}) do + def new_context(request, options \\ %{}) + + def new_context(%APIRequest{} = request, %{storage_state: storage} = options) when is_binary(storage) do + storage = Jason.decode!(File.read!(storage)) + new_context(request, Map.merge(options, %{storage_state: storage})) + end + + def new_context(%APIRequest{} = request, options) do Channel.post({request, :new_request}, options) end end diff --git a/lib/playwright/api_request_context.ex b/lib/playwright/api_request_context.ex index 879f789..60ad0d6 100644 --- a/lib/playwright/api_request_context.ex +++ b/lib/playwright/api_request_context.ex @@ -53,7 +53,6 @@ defmodule Playwright.APIRequestContext do """ use Playwright.SDK.ChannelOwner - alias ElixirLS.LanguageServer.Providers.Completion.Reducers.Returns alias Playwright.APIRequestContext alias Playwright.APIResponse alias Playwright.Request @@ -120,6 +119,20 @@ defmodule Playwright.APIRequestContext do required(:value) => String.t() } + @typedoc """ + Options for `dispose/2`. + """ + @type opts_dispose :: %{ + optional(:reason) => String.t() + } + + @typedoc """ + Options for `storage_state/2`. + """ + @type opts_storage :: %{ + optional(:path) => String.t() + } + # API # ---------------------------------------------------------------------------- @@ -154,6 +167,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:delete, [:context, :url]} + @pipe {:delete, [:context, :url, :options]} @spec delete(t(), binary(), options()) :: t() | {:error, Error.t()} def delete(context, url, options \\ %{}) @@ -188,7 +203,9 @@ defmodule Playwright.APIRequestContext do - `:ok` - `{:error, %Error{}}` """ - @spec dispose(t(), map()) :: :ok | {:error, Error.t()} + @pipe {:dispose, [:context]} + @pipe {:dispose, [:context, :options]} + @spec dispose(t(), opts_dispose()) :: :ok | {:error, Error.t()} def dispose(context, options \\ %{}) def dispose(%APIRequestContext{} = context, options) do @@ -257,6 +274,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:fetch, [:context, :url_or_request]} + @pipe {:fetch, [:context, :url_or_request, :options]} @spec fetch(t(), binary() | Request.t(), options()) :: APIResponse.t() | {:error, Error.t()} def fetch(context, url_or_request, options \\ %{}) @@ -303,6 +322,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:get, [:context, :url]} + @pipe {:get, [:context, :url, :options]} @spec get(t(), binary(), options()) :: t() | {:error, Error.t()} def get(context, url, options \\ %{}) @@ -341,6 +362,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:head, [:context, :url]} + @pipe {:head, [:context, :url, :options]} @spec head(t(), binary(), options()) :: t() | {:error, Error.t()} def head(context, url, options \\ %{}) @@ -382,6 +405,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:patch, [:context, :url]} + @pipe {:patch, [:context, :url, :options]} @spec patch(t(), binary(), options()) :: t() | {:error, Error.t()} def patch(context, url, options \\ %{}) @@ -422,6 +447,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:post, [:context, :url]} + @pipe {:post, [:context, :url, :options]} @spec post(t(), binary(), options()) :: t() | {:error, Error.t()} def post(context, url, options \\ %{}) @@ -462,6 +489,8 @@ defmodule Playwright.APIRequestContext do - `Playwright.APIResponse.t()` - `{:error, Error.t()}` """ + @pipe {:put, [:context, :url]} + @pipe {:put, [:context, :url, :options]} @spec put(t(), binary(), options()) :: t() | {:error, Error.t()} def put(context, url, options \\ %{}) @@ -493,8 +522,20 @@ defmodule Playwright.APIRequestContext do - `storage_state()` - `{:error, Error.t()}` """ - @spec storage_state(t(), map()) :: storage_state() + @pipe {:storage_state, [:context]} + @pipe {:storage_state, [:context, :options]} + @spec storage_state(t(), opts_storage()) :: storage_state() def storage_state(context, options \\ %{}) do - Channel.post({context, :storage_state}, options) + {path, options} = Map.pop(options, :path) + + case Channel.post({context, :storage_state}, options) do + {:error, _} = error -> + error + + result -> + result = Map.new(result) + path && File.write!(path, Jason.encode!(result)) + result + end end end diff --git a/lib/playwright/api_response.ex b/lib/playwright/api_response.ex index 552fcb4..92e35b8 100644 --- a/lib/playwright/api_response.ex +++ b/lib/playwright/api_response.ex @@ -12,6 +12,7 @@ defmodule Playwright.APIResponse do json = APIResponse.json(response) """ + use Playwright.SDK.Pipeline alias Playwright.APIRequestContext alias Playwright.APIResponse alias Playwright.API.Error @@ -54,6 +55,7 @@ defmodule Playwright.APIResponse do - `binary()` - `{:error, %Error{type: "ResponseError"}}` """ + @pipe {:body, [:response]} @spec body(t()) :: binary() | {:error, Error.t()} def body(%APIResponse{} = response) do case Channel.post({response.context, :fetch_response_body}, %{fetch_uid: response.fetchUid}) do @@ -77,6 +79,7 @@ defmodule Playwright.APIResponse do - `:ok` - `{:error, %Error{}}` """ + @pipe {:dispose, [:response]} @spec dispose(t()) :: :ok | {:error, Error.t()} def dispose(%APIResponse{} = response) do case Channel.post({response.context, "disposeAPIResponse"}, %{fetch_uid: response.fetchUid}) do @@ -110,6 +113,7 @@ defmodule Playwright.APIResponse do - `binary()` - `nil` """ + @pipe {:header, [:response, :name]} @spec header(t(), atom() | String.t()) :: binary() | nil def header(response, name) @@ -145,6 +149,7 @@ defmodule Playwright.APIResponse do - `serializable()` - `{:error, %Error{name: "ResponseError"}}` """ + @pipe {:json, [:response]} @spec json(t()) :: serializable() | {:error, Error.t()} def json(%APIResponse{} = response) do case body(response) do @@ -167,6 +172,7 @@ defmodule Playwright.APIResponse do Success means the response status code is within the range of `200-299`. """ + @pipe {:ok, [:response]} @spec ok(t()) :: boolean() def ok(%APIResponse{} = response) do response.status === 0 || (response.status >= 200 && response.status <= 299) @@ -180,6 +186,7 @@ defmodule Playwright.APIResponse do - `binary()` - `{:error, %Error{name: "ResponseError"}}` """ + @pipe {:text, [:response]} @spec text(t()) :: binary() | {:error, Error.t()} def text(%APIResponse{} = response) do body(response) diff --git a/mix.exs b/mix.exs index 075ffbf..ccb83ff 100644 --- a/mix.exs +++ b/mix.exs @@ -54,7 +54,7 @@ defmodule Playwright.MixProject do {:gun, "~> 1.3.3"}, {:jason, "~> 1.4"}, {:mix_audit, "~> 1.0", only: [:dev, :test], runtime: false}, - {:playwright_assets, "1.44.1", only: [:test]}, + {:playwright_assets, "1.44.2", only: [:test]}, {:recase, "~> 0.7"}, {:uuid, "~> 1.1"} ] diff --git a/mix.lock b/mix.lock index 8ce51f9..748310a 100644 --- a/mix.lock +++ b/mix.lock @@ -1,29 +1,29 @@ %{ "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, + "castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"}, "cowboy": {:hex, :cowboy, "2.6.3", "99aa50e94e685557cad82e704457336a453d4abcb77839ad22dbe71f311fcc06", [:rebar3], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "e5580029080f3f1ad17436fb97b0d5ed2ed4e4815a96bac36b5a992e20f58db6"}, "cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm", "1e1a3d176d52daebbecbbcdfd27c27726076567905c2a9d7398c54da9d225761"}, - "credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"}, - "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, - "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "credo": {:hex, :credo, "1.7.8", "9722ba1681e973025908d542ec3d95db5f9c549251ba5b028e251ad8c24ab8c5", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cb9e87cc64f152f3ed1c6e325e7b894dea8f5ef2e41123bd864e3cd5ceb44968"}, + "dialyxir": {:hex, :dialyxir, "1.4.4", "fb3ce8741edeaea59c9ae84d5cec75da00fa89fe401c72d6e047d11a61f65f70", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "cd6111e8017ccd563e65621a4d9a4a1c5cd333df30cebc7face8029cacb4eff6"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, + "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "esbuild": {:hex, :esbuild, "0.8.1", "0cbf919f0eccb136d2eeef0df49c4acf55336de864e63594adcea3814f3edf41", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "25fc876a67c13cb0a776e7b5d7974851556baeda2085296c14ab48555ea7560f"}, - "ex_doc": {:hex, :ex_doc, "0.34.0", "ab95e0775db3df71d30cf8d78728dd9261c355c81382bcd4cefdc74610bef13e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "60734fb4c1353f270c3286df4a0d51e65a2c1d9fba66af3940847cc65a8066d7"}, - "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"}, + "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"}, "gun": {:hex, :gun, "1.3.3", "cf8b51beb36c22b9c8df1921e3f2bc4d2b1f68b49ad4fbc64e91875aa14e16b4", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "3106ce167f9c9723f849e4fb54ea4a4d814e3996ae243a1c828b256e749041e0"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mix_audit": {:hex, :mix_audit, "1.0.1", "9dd114408961b8db214f42fee40b2f632ecd7e4fd29500403068c82c77db8361", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.8.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "65066bb7757078aa49faaa2f7c1e2d52f56ff6fe6cff01723dbaf5be2a75771b"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, - "playwright_assets": {:hex, :playwright_assets, "1.44.1", "61f1d0a0f0e6cccfa25cc84afda8ccaba3a472cfe73a30fd8c44dba7ca6102b8", [:mix], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:plug, "~> 1.12", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.1.3", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm", "be655593929e8ab5dba4be8e44c84f49a35a58c4ced162414494b090328fff2e"}, + "playwright_assets": {:hex, :playwright_assets, "1.44.2", "34f761b23703cf521567e1a3db003b4a6c07b6dafa37109bb82255da50df6442", [:mix], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:plug, "~> 1.12", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.1.3", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm", "0e80600ce4f6be0d2807bc8655bc5a5a722b32d5a005ebc8cebd8468ac3b0d42"}, "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_cowboy": {:hex, :plug_cowboy, "2.1.3", "38999a3e85e39f0e6bdfdf820761abac61edde1632cfebbacc445cdcb6ae1333", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "056f41f814dbb38ea44613e0f613b3b2b2f2c6afce64126e252837669eba84db"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"}, - "recase": {:hex, :recase, "0.8.0", "ec9500abee5d493d41e3cbfd7d51a4e10957a164570be0c805d5c6661b8cdbae", [:mix], [], "hexpm", "0d4b67b81e7897af77552bd1e6d6148717a4b45ec5c7b014a48b0ba9a28946b5"}, + "recase": {:hex, :recase, "0.8.1", "ab98cd35857a86fa5ca99036f575241d71d77d9c2ab0c39aacf1c9b61f6f7d1d", [:mix], [], "hexpm", "9fd8d63e7e43bd9ea385b12364e305778b2bbd92537e95c4b2e26fc507d5e4c2"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"}, "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, diff --git a/test/api/api_request_context_test.exs b/test/api/api_request_context_test.exs index 26f6172..bd0b8dc 100644 --- a/test/api/api_request_context_test.exs +++ b/test/api/api_request_context_test.exs @@ -1,14 +1,43 @@ defmodule Playwright.APIRequestContextTest do use Playwright.TestCase, async: true + alias Playwright.API.Error alias Playwright.APIRequest alias Playwright.APIResponse alias Playwright.APIRequestContext describe "APIRequestContext.delete/3" do - test "on success, returns `APIResponse`", %{assets: assets, session: session} do + test "on success, returns `APIResponse` w/ success status", %{assets: assets, session: session} do context = Playwright.request(session) |> APIRequest.new_context() - response = APIRequestContext.delete(context, assets.prefix <> "/simple.json") + %APIResponse{status: status} = response = APIRequestContext.delete(context, assets.prefix <> "/simple.json") + assert APIResponse.ok(response) + assert status == 200 + end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.delete(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.delete(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.delete!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.delete!(context, assets.prefix <> "/simple.json", options) + end end end @@ -21,12 +50,28 @@ defmodule Playwright.APIRequestContextTest do assert {:error, %{type: "TargetClosedError"}} = APIResponse.body(response) end + test "on failure, returns `{:error, error}`", %{session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + context = %{context | guid: "bogus"} + assert {:error, %Error{type: "TargetClosedError"}} = APIRequestContext.dispose(context) + end + test "succeeds when provided a 'reason'", %{session: session} do context = Playwright.request(session) |> APIRequest.new_context() assert :ok = APIRequestContext.dispose(context, %{reason: "Done!"}) end end + describe "APIRequestContext.dispose!/2" do + test "on failure, raises", %{session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + context = %{context | guid: "bogus"} + APIRequestContext.dispose!(context) + end + end + end + describe "APIRequestContext.fetch/3" do test "on success, returns `APIResponse` for each HTTP method", %{assets: assets, session: session} do methods = [:delete, :get, :head, :patch, :post, :put] @@ -50,6 +95,32 @@ defmodule Playwright.APIRequestContextTest do end end) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.fetch(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.fetch(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.fetch!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.fetch!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.get/3" do @@ -58,6 +129,32 @@ defmodule Playwright.APIRequestContextTest do response = APIRequestContext.get(context, assets.prefix <> "/simple.json") assert APIResponse.ok(response) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.get(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.get(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.get!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.get!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.head/3" do @@ -66,6 +163,32 @@ defmodule Playwright.APIRequestContextTest do response = APIRequestContext.head(context, assets.prefix <> "/simple.json") assert APIResponse.ok(response) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.head(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.head(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.head!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.head!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.patch/3" do @@ -74,6 +197,32 @@ defmodule Playwright.APIRequestContextTest do response = APIRequestContext.patch(context, assets.prefix <> "/simple.json") assert APIResponse.ok(response) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.patch(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.patch(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.patch!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.patch!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.post/3" do @@ -82,6 +231,32 @@ defmodule Playwright.APIRequestContextTest do response = APIRequestContext.post(context, assets.prefix <> "/simple.json") assert APIResponse.ok(response) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.post(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.post(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.post!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.post!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.put/3" do @@ -90,47 +265,84 @@ defmodule Playwright.APIRequestContextTest do response = APIRequestContext.put(context, assets.prefix <> "/simple.json") assert APIResponse.ok(response) end + + test "on 404, returns `APIResponse` w/ error status", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + %APIResponse{status: status} = response = APIRequestContext.put(context, assets.prefix <> "/bogus.json") + + refute APIResponse.ok(response) + assert status == 404 + end + + test "on failure, returns `{:error, error}`", %{assets: assets, session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + assert {:error, %Error{type: "RangeError"}} = APIRequestContext.put(context, assets.prefix <> "/simple.json", options) + end + end + + describe "APIRequestContext.put!/3" do + test "on failure, raises", %{assets: assets, session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + # fail: out-of-range timeout + options = %{timeout: -1} + APIRequestContext.put!(context, assets.prefix <> "/simple.json", options) + end + end end describe "APIRequestContext.storage_state/2" do test "(WIP) on success, ...", %{session: session} do # python: test_storage_state_should_round_trip_through_file # --- - context = - Playwright.request(session) - |> APIRequest.new_context(%{ - storage_state: %{ - cookies: [ - %{ - name: "cookie name", - value: "cookie value", - domain: "example.com", - path: "/", - expires: -1, - http_only: false, - secure: false, - same_site: "Lax" - } - ], - origins: [] + slug = DateTime.utc_now() |> DateTime.to_unix() + path = "storage-state-#{slug}.json" + + storage = %{ + cookies: [ + %{ + name: "cookie name", + value: "cookie value", + domain: "example.com", + path: "/", + expires: -1, + httpOnly: false, + secure: false, + sameSite: "Lax" } - }) - - assert [ - cookies: [ - %{ - name: "cookie name", - value: "cookie value", - domain: "example.com", - path: "/", - expires: -1, - httpOnly: false, - secure: false, - sameSite: "Lax" - } - ], - origins: [] - ] = APIRequestContext.storage_state(context) + ], + origins: [] + } + + request = Playwright.request(session) + context = APIRequest.new_context(request, %{storage_state: storage}) + + assert ^storage = APIRequestContext.storage_state(context, %{path: path}) + assert(File.exists?(path)) + assert(Jason.decode!(File.read!(path))) + + context = APIRequest.new_context(request, %{storage_state: path}) + assert ^storage = APIRequestContext.storage_state(context, %{path: path}) + + File.rm!(path) + end + + test "on failure, returns `{:error, error}`", %{session: session} do + context = Playwright.request(session) |> APIRequest.new_context() + context = %{context | guid: "bogus"} + assert {:error, %Error{type: "TargetClosedError"}} = APIRequestContext.storage_state(context) + end + end + + describe "APIRequestContext.storage_state!/2" do + test "on failure, raises", %{session: session} do + assert_raise RuntimeError, fn -> + context = Playwright.request(session) |> APIRequest.new_context() + context = %{context | guid: "bogus"} + APIRequestContext.storage_state!(context) + end end end end