# SPDX-License-Identifier: MIT defmodule Testcontainers.SeleniumContainer do @moduledoc """ Work in progress. Not stable for use yet. Not yet documented for this very reason. Can use https://github.com/stuart/elixir-webdriver for client in tests """ alias Testcontainers.ContainerBuilder alias Testcontainers.Container alias Testcontainers.SeleniumContainer alias Testcontainers.PortWaitStrategy alias Testcontainers.LogWaitStrategy import Testcontainers.Container, only: [is_valid_image: 1] @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 @enforce_keys [:image, :port1, :port2, :wait_timeout] defstruct [ :image, :port1, :port2, :wait_timeout, 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__{} = config, image) when is_binary(image) do %{config | image: image} end def with_port1(%__MODULE__{} = config, port1) when is_integer(port1) do %{config | port1: port1} end def with_port2(%__MODULE__{} = config, port2) when is_integer(port2) do %{config | port2: port2} end def with_wait_timeout(%__MODULE__{} = config, wait_timeout) when is_integer(wait_timeout) do %{config | wait_timeout: wait_timeout} end @doc """ Set the regular expression to check the image validity. """ def with_check_image(%__MODULE__{} = config, check_image) when is_valid_image(check_image) do %__MODULE__{config | check_image: check_image} end @doc """ Set the reuse flag to reuse the container if it is already running. """ def with_reuse(%__MODULE__{} = config, reuse) when is_boolean(reuse) do %__MODULE__{config | reuse: reuse} end def default_image, do: @default_image defimpl ContainerBuilder do import Container @spec build(%SeleniumContainer{}) :: %Container{} @impl true def build(%SeleniumContainer{} = config) do new(config.image) |> with_exposed_ports([config.port1, config.port2]) |> 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) ]) |> with_check_image(config.check_image) |> with_reuse(config.reuse) |> valid_image!() end @impl true def after_start(_config, _container, _conn), do: :ok end end