# SPDX-License-Identifier: MIT
defmodule TestcontainerEx.SeleniumContainer do
@moduledoc """
Work in progress. Not stable for use yet.
"""
alias TestcontainerEx.Container.Builder
alias TestcontainerEx.Container.Config
alias TestcontainerEx.LogWaitStrategy
alias TestcontainerEx.PortWaitStrategy
alias TestcontainerEx.SeleniumContainer
use TestcontainerEx.ContainerConfig
@default_image "selenium/standalone-chrome"
@default_tag "118.0"
@default_image_with_tag "#{@default_image}:#{@default_tag}"
@default_port1 7900
@default_port2 4400
@default_wait_timeout 120_000
@type t :: %__MODULE__{}
@enforce_keys [:image, :port1, :port2, :wait_timeout]
defstruct [
:image,
:port1,
:port2,
:wait_timeout,
:name,
check_image: @default_image,
reuse: false
]
def new,
do: %__MODULE__{
image: @default_image_with_tag,
wait_timeout: @default_wait_timeout,
port1: @default_port1,
port2: @default_port2
}
def with_image(%__MODULE__{} = c, image) when is_binary(image), do: %{c | image: image}
def with_port1(%__MODULE__{} = c, p) when is_integer(p), do: %{c | port1: p}
def with_port2(%__MODULE__{} = c, p) when is_integer(p), do: %{c | port2: p}
def with_wait_timeout(%__MODULE__{} = c, t) when is_integer(t), do: %{c | wait_timeout: t}
@doc """
Sets the container name.
"""
@spec with_name(t(), String.t()) :: t()
def with_name(%__MODULE__{} = config, name) when is_binary(name) do
%__MODULE__{config | name: name}
end
def default_image, do: @default_image
defimpl Builder do
@spec build(SeleniumContainer.t()) :: Config.t()
@impl true
def build(%SeleniumContainer{} = config) do
Config.new(config.image)
|> Config.with_exposed_ports([config.port1, config.port2])
|> Config.with_waiting_strategies([
LogWaitStrategy.new(
~r/.*(RemoteWebDriver instances should connect to|Selenium Server is up and running|Started Selenium Standalone).*\n/,
config.wait_timeout,
1000
),
PortWaitStrategy.new("127.0.0.1", config.port1, config.wait_timeout, 1000),
PortWaitStrategy.new("127.0.0.1", config.port2, config.wait_timeout, 1000)
])
|> Config.with_check_image(config.check_image)
|> Config.with_reuse(config.reuse)
|> then(fn cfg ->
if config.name, do: Config.with_name(cfg, config.name), else: cfg
end)
|> Config.valid_image!()
end
@impl true
def after_start(_config, _container, _conn), do: :ok
end
end