Packages
wallaby
0.21.0
0.31.0
0.30.12
0.30.11
0.30.10
0.30.9
0.30.8
0.30.7
0.30.6
0.30.5
0.30.4
0.30.3
0.30.2
0.30.1
0.30.0
0.29.1
0.29.0
0.28.1
0.28.0
0.27.0
0.26.2
0.26.1
0.26.0
0.25.1
0.25.0
0.24.1
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.0
0.16.1
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.1
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.1
0.3.0
0.2.0
0.1.0
0.0.1
Concurrent feature tests for elixir
Current section
Files
Jump to
Current section
Files
lib/wallaby/experimental/selenium/webdriver_client.ex
defmodule Wallaby.Experimental.Selenium.WebdriverClient do
@moduledoc false
alias Wallaby.{Driver, Element, Query, Session}
alias Wallaby.Helpers.KeyCodes
import Wallaby.HTTPClient
@type http_method :: :post | :get | :delete
@type url :: String.t
@web_element_identifier "element-6066-11e4-a52e-4f735466cecf"
@doc """
Create a session with the base url.
"""
@spec create_session(String.t, map) :: {:ok, map}
def create_session(base_url, capabilities) do
params = %{desiredCapabilities: capabilities}
request(:post, "#{base_url}session", params)
end
@doc """
Deletes a session with the driver.
"""
@spec delete_session(Session.t | Element.t) :: {:ok, map}
def delete_session(session) do
request(:delete, session.session_url, %{})
end
@doc """
Finds an element on the page for a session. If an element is provided then
the query will be scoped to within that element.
"""
@spec find_elements(Session.t | Element.t, Query.compiled) :: {:ok, [Element.t]}
def find_elements(parent, locator) do
with {:ok, resp} <- request(:post, parent.url <> "/elements", to_params(locator)),
{:ok, elements} <- Map.fetch(resp, "value"),
elements <- Enum.map(elements || [], &(cast_as_element(parent, &1))),
do: {:ok, elements}
end
@doc """
Sets the value of an element.
"""
@spec set_value(Element.t, String.t) :: {:ok, nil} | {:error, Driver.reason}
def set_value(%Element{url: url}, value) do
case request(:post, "#{url}/value", %{value: [value]}) do
{:ok, resp} -> {:ok, Map.get(resp, "value")}
{:error, reason} -> {:error, reason}
end
end
@doc """
Clears the value in an element
"""
@spec clear(Element.t) :: {:ok, nil} | {:error, Driver.reason}
def clear(%Element{url: url}) do
case request(:post, "#{url}/clear") do
{:ok, resp} -> {:ok, Map.get(resp, "value")}
{:error, reason} -> {:error, reason}
end
end
@doc """
Invoked to accept one alert triggered within `open_dialog_fn` and return the alert message.
"""
def accept_alert(session, fun) do
fun.(session)
with {:ok, value} <- alert_text(session),
{:ok, _r} <- request(:post, "#{session.url}/accept_alert"),
do: value
end
@doc """
Invoked to accept one alert triggered within `open_dialog_fn` and return the alert message.
"""
def dismiss_alert(session, fun) do
accept_alert(session, fun)
end
def accept_confirm(session, fun) do
accept_alert(session, fun)
end
def dismiss_confirm(session, fun) do
fun.(session)
with {:ok, value} <- alert_text(session),
{:ok, _r} <- request(:post, "#{session.url}/dismiss_alert"),
do: value
end
def accept_prompt(session, input, fun) when is_nil(input) do
fun.(session)
with {:ok, value} <- alert_text(session),
{:ok, _r} <- request(:post, "#{session.url}/accept_alert"),
do: value
end
def accept_prompt(session, input, fun) do
fun.(session)
with {:ok, _r} <- request(:post, "#{session.url}/alert_text", %{text: input}),
{:ok, value} <- alert_text(session),
{:ok, _r} <- request(:post, "#{session.url}/accept_alert"),
do: value
end
def dismiss_prompt(session, fun) do
fun.(session)
with {:ok, value} <- alert_text(session),
{:ok, _resp} <- request(:post, "#{session.url}/alert/dismiss"),
do: value
end
@doc """
Clicks an element
"""
@spec click(Element.t) :: {:ok, map}
def click(%Element{url: url}) do
with {:ok, resp} <- request(:post, "#{url}/click"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the text for an element
"""
@spec text(Element.t) :: {:ok, String.t}
def text(element) do
with {:ok, resp} <- request(:get, "#{element.url}/text"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the title of the current page.
"""
@spec page_title(Session.t) :: {:ok, String.t}
def page_title(session) do
with {:ok, resp} <- request(:get, "#{session.url}/title"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the value of an elements attribute
"""
@spec attribute(Element.t, String.t) :: {:ok, String.t}
def attribute(element, name) do
with {:ok, resp} <- request(:get, "#{element.url}/attribute/#{name}"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Visit a specific page.
"""
@spec visit(Session.t, String.t) :: :ok
def visit(session, path) do
with {:ok, resp} <- request(:post, "#{session.url}/url", %{url: path}),
{:ok, _} <- Map.fetch(resp, "value"),
do: :ok
end
@doc """
Gets the current url.
"""
@spec current_url(Session.t) :: {:ok, String.t} | {:error, any()}
def current_url(session) do
with {:ok, resp} <- request(:get, "#{session.url}/url"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the current path or nil.
"""
@spec current_path(Session.t) :: {:ok, String.t} | {:error, any()}
def current_path(session) do
with {:ok, url} <- current_url(session),
uri <- URI.parse(url),
{:ok, path} <- Map.fetch(uri, :path),
do: {:ok, path}
end
@doc """
Gets the selected value of the element.
For Checkboxes and Radio buttons it returns the selected option.
For options selects it returns the selected option
"""
@spec selected(Element.t) :: {:ok, boolean} | {:error, :stale_reference}
def selected(element) do
with {:ok, resp} <- request(:get, "#{element.url}/selected"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Checks if the element is being displayed.
This is based on what is available in phantom and doesn't match the current
specification.
"""
@spec displayed(Element.t) :: {:ok, boolean} | {:error, :stale_reference}
def displayed(element) do
with {:ok, resp} <- request(:get, "#{element.url}/displayed"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the size of a element.
This is non-standard and only works in Phantom.
"""
@spec size(Element.t) :: {:ok, any}
def size(element) do
with {:ok, resp} <- request(:get, "#{element.url}/size"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the height, width, x, and y position of an Element.
This is based on the standard but currently is un-supported by Phantom.
"""
@spec rect(Element.t) :: {:ok, any}
def rect(element) do
with {:ok, resp} <- request(:get, "#{element.url}/rect"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Takes a screenshot.
"""
@spec take_screenshot(Session.t | Element.t) :: binary
def take_screenshot(session) do
with {:ok, resp} <- request(:get, "#{session.session_url}/screenshot"),
{:ok, value} <- Map.fetch(resp, "value"),
decoded_value <- :base64.decode(value),
do: decoded_value
end
@doc """
Gets the cookies for a session.
"""
@spec cookies(Session.t) :: {:ok, [map]}
def cookies(session) do
with {:ok, resp} <- request(:get, "#{session.url}/cookie"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Sets a cookie for the session.
"""
@spec set_cookie(Session.t, String.t, String.t) :: {:ok, []}
def set_cookie(session, key, value) do
with {:ok, resp} <- request(:post, "#{session.url}/cookie", %{cookie: %{name: key, value: value}}),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Sets the size of the window.
"""
@spec set_window_size(Session.t, non_neg_integer, non_neg_integer) :: {:ok, map}
@spec set_window_size(Session.t, String.t, non_neg_integer, non_neg_integer) :: {:ok, map}
def set_window_size(session, width, height) do
with {:ok, resp} <- request(:post, "#{session.url}/window/rect", %{width: width, height: height}),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
def set_window_size(session, window_handle, width, height) do
with {:ok, resp} <- request(:post, "#{session.url}/window/#{window_handle}/size", %{width: width, height: height}),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Gets the size of the window
"""
@spec get_window_size(Session.t) :: {:ok, map}
@spec get_window_size(Session.t, String.t) :: {:ok, map}
def get_window_size(session) do
with {:ok, resp} <- request(:get, "#{session.url}/window/rect"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
def get_window_size(session, window_handle) do
with {:ok, resp} <- request(:get, "#{session.url}/window/#{window_handle}/size"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Executes javascript synchoronously, taking as arguments the script to execute,
and optionally a list of arguments available in the script via `arguments`
"""
@spec execute_script(Session.t | Element.t, String.t, Keyword.t) :: {:ok, any}
def execute_script(session, script, arguments \\ []) do
with {:ok, resp} <- request(:post, "#{session.session_url}/execute", %{script: script, args: arguments}),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Sends a list of key strokes to active element
"""
@spec send_keys(Session.t, [String.t | atom]) :: {:ok, nil}
def send_keys(%Session{} = session, keys) when is_list(keys) do
with {:ok, resp} <- request(:post, "#{session.session_url}/keys", KeyCodes.json(keys), encode_json: false),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
def send_keys(parent, keys) when is_list(keys) do
with {:ok, resp} <- request(:post, "#{parent.url}/value", KeyCodes.json(keys), encode_json: false),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Retrieves logs from the browser
"""
@spec log(Session.t | Element.t) :: {:ok, [map]}
def log(session) do
with {:ok, resp} <- request(:post, "#{session.session_url}/log", %{type: "browser"}),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Retrieves the current page source from session
"""
@spec page_source(Session.t) :: {:ok, String.t}
def page_source(session) do
with {:ok, resp} <- request(:get, "#{session.url}/source"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
def window_handles(session) do
with {:ok, resp} <- request(:get, "#{session.url}/window_handles"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
@doc """
Retrieves the window handle for from session
"""
@spec window_handle(Session.t) :: String.t
def window_handle(session) do
with {:ok, resp} <- request(:get, "#{session.url}/window_handle"),
{:ok, value} <- Map.fetch(resp, "value"),
do: value
end
@spec cast_as_element(Session.t | Element.t, map) :: Element.t
defp cast_as_element(parent, %{"ELEMENT" => id}) do
cast_as_element(parent, %{@web_element_identifier => id})
end
defp cast_as_element(parent, %{@web_element_identifier => id}) do
%Wallaby.Element{
id: id,
session_url: parent.session_url,
url: parent.session_url <> "/element/#{id}",
parent: parent,
driver: parent.driver,
}
end
# Retrieves the text from an alert, prompt or confirm.
@spec alert_text(Session.t) :: {:ok, String.t}
defp alert_text(session) do
with {:ok, resp} <- request(:get, "#{session.url}/alert_text"),
{:ok, value} <- Map.fetch(resp, "value"),
do: {:ok, value}
end
end