Skip to content

Add geckodriver support #237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ For browser automation and writing integration tests in Elixir.

* Can run __multiple browser sessions__ simultaneously. [See example](https://github.com/HashNuke/hound/blob/master/test/multiple_browser_session_test.exs).

* Supports Selenium (Firefox, Chrome), ChromeDriver and PhantomJs.
* Supports Selenium (Firefox, Chrome), ChromeDriver, geckodriver (note: [only supports a single session for now](https://github.com/mozilla/geckodriver/issues/882)) and PhantomJs.

* Supports Javascript-heavy apps. Retries a few times before reporting error.

Expand Down
2 changes: 2 additions & 0 deletions lib/hound/connection_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ defmodule Hound.ConnectionServer do
{9515, nil, "chrome"}
"phantomjs" ->
{8910, nil, "phantomjs"}
"geckodriver" ->
{4444, nil, "firefox"}
_ -> # assume selenium
{4444, "wd/hub/", "firefox"}
end
Expand Down
26 changes: 22 additions & 4 deletions lib/hound/helpers/element.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ defmodule Hound.Helpers.Element do

@spec inner_html(Hound.Element.selector) :: String.t
def inner_html(element) do
attribute_value(element, "innerHTML")
property_value(element, "innerHTML")
end


@spec inner_text(Hound.Element.selector) :: String.t
def inner_text(element) do
attribute_value(element, "innerText")
property_value(element, "innerText")
end

@spec outer_html(Hound.Element.selector) :: String.t
def outer_html(element) do
attribute_value(element, "outerHTML")
property_value(element, "outerHTML")
end

@doc """
Expand Down Expand Up @@ -166,6 +166,24 @@ defmodule Hound.Helpers.Element do
end


@doc """
Gets an element's property value.

element = find_element(:name, "example")
property_value(element, "innerHTML")

You can also pass the selector as a tuple, for the first argument

property_value({:name, "example"}, "innerHTML")
"""
@spec property_value(Hound.Element.selector, String.t) :: String.t | :nil
def property_value(element, property_name) do
element = get_element(element)
session_id = Hound.current_session_id
make_req(:get, "session/#{session_id}/element/#{element}/property/#{property_name}")
end


@doc """
Checks if an element has a given class.

Expand Down
1 change: 1 addition & 0 deletions lib/hound/internal_helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule Hound.InternalHelpers do
"focus_parent_frame"
],
chrome_driver: [],
geckodriver: [],
selenium: []
]

Expand Down
5 changes: 4 additions & 1 deletion lib/hound/request_utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,14 @@ defmodule Hound.RequestUtils do
{"chrome_driver", _} ->
Hound.ResponseParsers.ChromeDriver

{"geckodriver", _} ->
Hound.ResponseParsers.GeckoDriver

{"phantomjs", _} ->
Hound.ResponseParsers.PhantomJs

other_driver ->
raise "No response parser found for #{other_driver}"
raise "No response parser found for #{inspect other_driver}"
end
end

Expand Down
5 changes: 4 additions & 1 deletion lib/hound/response_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ defmodule Hound.ResponseParser do
def handle_response(_mod, "session", code, %{"sessionId" => session_id}) when code < 300 do
{:ok, session_id}
end
def handle_response(_mod, "session", code, %{"value" => %{"sessionId" => session_id}}) when code < 300 do
{:ok, session_id}
end
def handle_response(mod, _path, _code, %{"value" => %{"message" => message} = value}) do
if mod.warning?(message) do
Logger.warn(message)
Expand All @@ -51,7 +54,7 @@ defmodule Hound.ResponseParser do
mod.handle_error(value)
end
end
def handle_response(_mod, _path, _code, %{"status" => 0, "value" => value}), do: value
def handle_response(_mod, _path, _code, %{"value" => value}), do: value
def handle_response(_mod, _path, code, _body) when code < 400, do: :ok
def handle_response(_mod, _path, _code, _body), do: :error

Expand Down
9 changes: 9 additions & 0 deletions lib/hound/response_parsers/geckodriver.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Hound.ResponseParsers.GeckoDriver do
@moduledoc false

use Hound.ResponseParser

def handle_error(%{"message" => "Unable to locate element:" <> _rest}) do
{:error, :no_such_element}
end
end