defmodule Playwright.Config do
@moduledoc """
Configuration for Playwright.
## Overview
config :playwright, ConnectOptions,
[...]
config :playwright, LaunchOptions,
[...]
config :playwright, PlaywrightTest,
[...]
## Details for `ConnectOptions`
Configuration for connecting to a running Playwright browser server over a
WebSocket.
### `ws_endpoint` (required)
A browser websocket endpoint to which the runner will connect.
This option is required when using the `:driver` transport to communicate with
a Playwright browser server.
e.g.,
config :playwright, ConnectOptions,
ws_endpoint: "ws://localhost:3000/playwright"
## Details for `LaunchOptions`
Configuration for Playwright browser server launch commands.
### `args` (optional)
Additional arguments to pass to the browser instance. The list of Chromium
flags may be found [online](http://peter.sh/experiments/chromium-command-line-switches/).
e.g.,
config :playwright, LaunchOptions,
args: [
"--use-fake-ui-for-media-stream",
"--use-fake-device-for-media-stream"
]
### `channel` (optional)
Browser distribution channel for Chromium. Supported values are:
- `chrome`
- `chrome-beta`
- `chrome-dev`
- `chrome-canary`
- `msedge`
- `msedge-beta`
- `msedge-dev`
- `msedge-canary`
Read more about using Google Chrome and Microsoft Edge
[online](https://playwright.dev/docs/browsers#google-chrome--microsoft-edge).
e.g.,
config :playwright, LaunchOptions,
channel: "chrome"
### `chromium_sandbox` (optional)
Enable Chromium sandboxing. Defaults to `false`.
e.g.,
config :playwright, LaunchOptions,
chromium_sandbox: true
### `devtools` (optional)
With Chromium, specifies whether to auto-open a "Developer Tools" panel for
each tab. If this option is `true`, the `headless` option will be set to
`false`.
Defaults to `false`.
e.g.,
config :playwright, LaunchOptions,
devtools: true
### `headless` (optional)
Specifies whether to run the browser in "headless" mode. See:
- [headless Chromium](https://developers.google.com/web/updates/2017/04/headless-chrome)
- [headless Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode)
Defaults to `true` unless the `devtools` option is `true`.
e.g.,
config :playwright, LaunchOptions,
headless: false # e.g., see a browser window pop up in "dev".
### `downloads_path` (optional)
**WARNING: not yet implemented**
If specified, accepted downloads are written to this directory. Otherwise, a
temporary directory is created and is removed when the browser is closed.
e.g.,
config :playwright, LaunchOptions,
downloads_path: "./doc/downloads"
### `env` (optional)
**WARNING: not yet implemented**
Environment variables that will be made visible to the browser. Defaults to
`System.get_env/0`.
e.g.,
config :playwright, LaunchOptions,
env: ["DEBUG", "true"]
### `executable_path` (optional)
A filesystem path to a browser executable to run instead of the bundled
browser. If `executable_path` is a relative path, then it is resolved relative
to the current working directory.
**Chromium-only**
Playwright can also be used to control the Google Chrome or Microsoft Edge
browsers, but it works best with the bundled version of Chromium. There is no
guarantee that it will work with any other version.
**Use `executable_path` option with extreme caution.**
e.g.,
config :playwright, LaunchOptions,
executable_path: "/Applications/..."
### `playwright_cli_path` (optional)
A filesystem path to the playwright cli.js file to use instead of the default
assets path.
**Chromium-only**
This can be helpful for packaged releases or systems where the node_module may
be located elsewhere on the filesystem.
**Use `playwright_cli_path` option with extreme caution.**
e.g.,
config :playwright, ConnectOptions,
playwright_cli_path: "/Cache/.../playwright/cli.js"
## Details for `PlaywrightTest`
Configuration for usage of `PlaywrightTest.Case`.
### `transport` (optional)
One of `:driver` or `:websocket`, defaults to `:driver`.
Additional configuration may be required depending on the transport
configuration:
- `LaunchOptions` for the `:driver` transport
- `ConnectOptions` for the `:websocket` transport
e.g.,
config :playwright, PlaywrightTest,
transport: :websocket
"""
alias Playwright.Config.Types
@typedoc false
@type connect_options :: %{
ws_endpoint: String.t()
}
@typedoc false
@type launch_options :: %{
args: [String.t()],
channel: String.t(),
chromium_sandbox: boolean(),
devtools: boolean(),
downloads_path: String.t(),
env: any(),
executable_path: String.t(),
headless: boolean(),
playwright_cli_path: String.t()
}
@typedoc false
@type playwright_test :: %{
transport: atom()
}
defmodule Types do
@moduledoc false
defmodule ConnectOptions do
@moduledoc false
defstruct [:ws_endpoint, :playwright_cli_path]
end
defmodule LaunchOptions do
@moduledoc false
defstruct [
:args,
:channel,
:chromium_sandbox,
:devtools,
:downloads_path,
:executable_path,
:headless,
:playwright_cli_path
]
end
defmodule PlaywrightTest do
@moduledoc false
defstruct transport: :driver
end
end
@doc false
@spec connect_options() :: connect_options
def connect_options() do
config_for(ConnectOptions, %Types.ConnectOptions{}) || %{}
end
@doc false
@spec launch_options() :: map()
def launch_options() do
config_for(LaunchOptions, %Types.LaunchOptions{}) || %{}
# |> clean()
end
@doc false
@spec playwright_test() :: Types.PlaywrightTest
def playwright_test() do
config_for(PlaywrightTest, %Types.PlaywrightTest{})
# |> Map.from_struct()
end
@doc false
def config_for(key, mod) do
configured =
Application.get_env(:playwright, key, %{})
|> Enum.into(%{})
build(configured, mod)
|> clean()
end
# private
# ----------------------------------------------------------------------------
defp build(source, mod) do
result =
for key <- Map.keys(mod) |> Enum.reject(fn key -> key == :__struct__ end),
into: %{} do
case Map.get(source, key) do
nil ->
{key, Map.get(mod, key)}
value ->
{key, value}
end
end
Map.merge(mod, result)
end
defp clean(source) do
Map.from_struct(source)
|> Enum.reject(fn
{_key, value} when is_nil(value) -> true
{_key, value} when is_list(value) -> value == []
_otherwise_ -> false
end)
|> Enum.into(%{})
end
end