16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/test/browsers/phantomjs_test.exs:
--------------------------------------------------------------------------------
1 | defmodule Hound.Browser.PhantomJSTest do
2 | use ExUnit.Case
3 |
4 | alias Hound.Browser.PhantomJS
5 |
6 | test "default_user_agent" do
7 | assert PhantomJS.default_user_agent == :phantomjs
8 | end
9 |
10 | test "default_capabilities" do
11 | ua = Hound.Browser.user_agent(:iphone)
12 | assert PhantomJS.default_capabilities(ua) == %{"phantomjs.page.settings.userAgent" => ua}
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/test/element_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ElementTest do
2 | use ExUnit.Case
3 |
4 | alias Hound.Element
5 |
6 | test "encoding to JSON" do
7 | uuid = "some-uuid"
8 | element = %Element{uuid: uuid}
9 | assert Jason.encode!(element) == ~s({"ELEMENT":"#{uuid}"})
10 | end
11 |
12 | test "string representation" do
13 | uuid = "some-uuid"
14 | element = %Element{uuid: uuid}
15 | assert to_string(element) == uuid
16 | end
17 |
18 | test "element?/1" do
19 | assert Element.element?(%Element{uuid: "foo"})
20 | refute Element.element?("foo")
21 | end
22 |
23 | test "from_response/1" do
24 | assert Element.from_response(%{"ELEMENT" => "uuid"}) == %Element{uuid: "uuid"}
25 | assert_raise Hound.InvalidElementError, fn -> Element.from_response(%{"value" => "foo"}) end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/test/exceptions_test.exs:
--------------------------------------------------------------------------------
1 | defmodule HoundNotSupportedErrorTest do
2 | use ExUnit.Case
3 |
4 | test "message" do
5 | {:ok, info} = Hound.ConnectionServer.driver_info
6 | function_name = "foo"
7 | err = try do
8 | raise Hound.NotSupportedError, function: function_name
9 | rescue
10 | e -> Exception.message(e)
11 | end
12 | assert err =~ "not supported"
13 | assert err =~ function_name
14 | assert err =~ info.driver
15 | assert err =~ info.browser
16 | end
17 |
18 | defmodule DummyRaiser do
19 | require Hound.NotSupportedError
20 |
21 | def foo do
22 | Hound.NotSupportedError.raise_for(%{driver: "selenium", browser: "firefox"})
23 | :ok
24 | end
25 | end
26 |
27 | test "raise_for" do
28 | if match?({:ok, %{driver: "selenium", browser: "firefox"}}, Hound.ConnectionServer.driver_info) do
29 | assert_raise Hound.NotSupportedError, fn ->
30 | DummyRaiser.foo
31 | end
32 | else
33 | assert DummyRaiser.foo == :ok
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/test/helpers/cookie_test.exs:
--------------------------------------------------------------------------------
1 | defmodule CookieTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | @domain "localhost:9090"
6 |
7 | setup do
8 | Hound.start_session
9 | if Hound.InternalHelpers.driver_supports?("delete_cookies") do
10 | delete_cookies()
11 | end
12 |
13 | parent = self()
14 | on_exit fn->
15 | # NOTE PhantomJs uses the same cookie jar for all sessions.
16 | # We'll delete cookies after each session, because we only want to test our APIs
17 | Hound.end_session(parent)
18 | end
19 | :ok
20 | end
21 |
22 |
23 | test "should set a cookie" do
24 | navigate_to "http://#{@domain}/page1.html"
25 | cart_id = "12v3q4rsdv"
26 | safe_set_cookie(%{name: "cart_id", value: cart_id})
27 | valid_cookie = Enum.find(cookies(), fn(cookie)-> cookie["name"]=="cart_id" end)
28 |
29 | assert valid_cookie["value"] == cart_id
30 | end
31 |
32 |
33 | test "should get cookies on page" do
34 | navigate_to "http://#{@domain}/page1.html"
35 | safe_set_cookie(%{name: "example", value: "12v3q4rsdv"})
36 |
37 | assert length(cookies()) >= 1
38 | end
39 |
40 |
41 | test "should delete a cookie" do
42 | navigate_to "http://#{@domain}/page1.html"
43 | cart_id = "12v3q4rsdv"
44 | safe_set_cookie(%{name: "cart_id", value: cart_id})
45 | safe_set_cookie(%{name: "cart_status", value: "active"})
46 |
47 |
48 | assert length(cookies()) >= 2
49 | delete_cookie("cart_id")
50 | assert length(cookies()) >= 1
51 | end
52 |
53 |
54 | test "should delete all cookies" do
55 | navigate_to "http://#{@domain}/page1.html"
56 | cart_id = "12v3q4rsdv"
57 | safe_set_cookie(%{name: "cart_id", value: cart_id})
58 | safe_set_cookie(%{name: "cart_status", value: "active"})
59 |
60 | assert length(cookies()) >= 2
61 | delete_cookies()
62 | assert length(cookies()) >= 0
63 | end
64 |
65 | # NOTE: avoids bug with recent versions of phantomjs
66 | # see: https://github.com/ariya/phantomjs/issues/14047
67 | defp safe_set_cookie(cookie, retry \\ true) do
68 | try do
69 | set_cookie(cookie)
70 | rescue
71 | _ ->
72 | if retry, do: safe_set_cookie(Map.put(cookie, :domain, @domain), false)
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/test/helpers/dialog_test.exs:
--------------------------------------------------------------------------------
1 | defmodule DialogTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | if Hound.InternalHelpers.driver_supports?("dialog_text") do
6 |
7 | hound_session()
8 |
9 | test "Get dialog text" do
10 | navigate_to "http://localhost:9090/page1.html"
11 | execute_script("alert('hello')")
12 | assert dialog_text() == "hello"
13 | end
14 |
15 |
16 | test "Dismiss dialog" do
17 | navigate_to "http://localhost:9090/page1.html"
18 | execute_script("return window.isItReal = confirm('Is it true?')")
19 | dismiss_dialog()
20 | assert execute_script("return window.isItReal") == false
21 | end
22 |
23 |
24 | test "Accept dialog" do
25 | navigate_to "http://localhost:9090/page1.html"
26 | execute_script("return window.isItReal = confirm('Is it true?')")
27 | accept_dialog()
28 | assert execute_script("return window.isItReal") == true
29 | end
30 |
31 |
32 | test "Input into prompt" do
33 | navigate_to "http://localhost:9090/page1.html"
34 | execute_script("return window.isItReal = prompt('Is it true?')")
35 | input_into_prompt("Yes it is")
36 | accept_dialog()
37 | assert execute_script("return window.isItReal") == "Yes it is"
38 | end
39 |
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/test/helpers/element_with_ids_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ElementTestWithIds do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should get visible text of an element" do
8 | navigate_to "http://localhost:9090/page1.html"
9 | element = find_element(:class, "example")
10 | assert visible_text(element) == "Paragraph"
11 | end
12 |
13 |
14 | test "should input value into field" do
15 | navigate_to "http://localhost:9090/page1.html"
16 | element = find_element(:name, "username")
17 |
18 | input_into_field(element, "john")
19 | assert attribute_value(element, "value") == "john"
20 |
21 | input_into_field(element, "doe")
22 | assert attribute_value(element, "value") == "johndoe"
23 | end
24 |
25 |
26 | test "should fill a field with a value" do
27 | navigate_to "http://localhost:9090/page1.html"
28 | element = find_element(:name, "username")
29 |
30 | fill_field(element, "johndoe")
31 | assert attribute_value(element, "value") == "johndoe"
32 |
33 | fill_field(element, "janedoe")
34 | assert attribute_value(element, "value") == "janedoe"
35 | end
36 |
37 |
38 | test "should get tag name of element" do
39 | navigate_to "http://localhost:9090/page1.html"
40 | element = find_element(:name, "username")
41 | assert tag_name(element) == "input"
42 | end
43 |
44 |
45 | test "should clear field" do
46 | navigate_to "http://localhost:9090/page1.html"
47 | element = find_element(:name, "username")
48 | fill_field(element, "johndoe")
49 | assert attribute_value(element, "value") == "johndoe"
50 |
51 | clear_field(element)
52 | assert attribute_value(element, "value") == ""
53 | end
54 |
55 |
56 | test "should return true if item is selected in a checkbox or radio" do
57 | navigate_to "http://localhost:9090/page1.html"
58 | element = find_element :id, "speed-superpower"
59 | click element
60 | assert selected?(element)
61 | end
62 |
63 |
64 | test "should return false if item is *not* selected" do
65 | navigate_to "http://localhost:9090/page1.html"
66 | element = find_element :id, "speed-flying"
67 | assert selected?(element) == false
68 | end
69 |
70 |
71 | test "Should return true if element is enabled" do
72 | navigate_to "http://localhost:9090/page1.html"
73 | element = find_element(:name, "username")
74 | assert element_enabled?(element) == true
75 | end
76 |
77 |
78 | test "Should return false if element is *not* enabled" do
79 | navigate_to "http://localhost:9090/page1.html"
80 | element = find_element(:name, "promocode")
81 | assert element_enabled?(element) == false
82 | end
83 |
84 |
85 | test "should get attribute value of an element" do
86 | navigate_to "http://localhost:9090/page1.html"
87 | element = find_element(:class, "example")
88 | assert attribute_value(element, "data-greeting") == "hello"
89 | end
90 |
91 |
92 | test "should return true if an element is displayed" do
93 | navigate_to "http://localhost:9090/page1.html"
94 | element = find_element(:class, "example")
95 | assert element_displayed?(element)
96 | end
97 |
98 |
99 | test "should return false if an element is *not* displayed" do
100 | navigate_to "http://localhost:9090/page1.html"
101 | element = find_element(:class, "hidden-element")
102 | assert element_displayed?(element) == false
103 | end
104 |
105 |
106 | test "should get an element's location on screen" do
107 | navigate_to "http://localhost:9090/page1.html"
108 | element = find_element :class, "example"
109 | {loc_x, loc_y} = element_location(element)
110 | assert is_integer(loc_x) || is_float(loc_x)
111 | assert is_integer(loc_y) || is_float(loc_y)
112 | end
113 |
114 |
115 | test "should get an element's size" do
116 | navigate_to "http://localhost:9090/page1.html"
117 | element = find_element(:class, "example")
118 | size = element_size(element)
119 | assert size == {400, 100}
120 | end
121 |
122 |
123 | test "should get css property of an element" do
124 | navigate_to "http://localhost:9090/page1.html"
125 | element = find_element(:class, "container")
126 | assert css_property(element, "display") == "block"
127 | end
128 |
129 |
130 | test "should click on an element" do
131 | navigate_to "http://localhost:9090/page1.html"
132 | element = find_element(:class, "submit-form")
133 | click element
134 | assert current_url() == "http://localhost:9090/page2.html"
135 | end
136 |
137 |
138 | test "should submit a form element" do
139 | navigate_to "http://localhost:9090/page1.html"
140 | element = find_element(:name, "username")
141 | submit_element(element)
142 | Process.sleep(50)
143 | assert current_url() == "http://localhost:9090/page2.html"
144 | end
145 |
146 | test "should move mouse to an element" do
147 | navigate_to "http://localhost:9090/page1.html"
148 | element = find_element(:id, "mouse-actions")
149 | move_to(element, 5, 5)
150 | assert visible_text({:id, "mouse-actions"}) == "Mouse over"
151 | end
152 |
153 | test "should mouse down on an element" do
154 | navigate_to "http://localhost:9090/page1.html"
155 | element = find_element(:id, "mouse-actions")
156 | move_to(element, 5, 5)
157 | mouse_down()
158 | assert visible_text({:id, "mouse-actions"}) == "Mouse down"
159 | end
160 |
161 | test "should mouse up on an element" do
162 | navigate_to "http://localhost:9090/page1.html"
163 | element = find_element(:id, "mouse-actions")
164 | move_to(element, 5, 5)
165 | # Mouse up needs a mouse down before
166 | mouse_down()
167 | mouse_up()
168 | assert visible_text({:id, "mouse-actions"}) == "Mouse up"
169 | end
170 | end
171 |
--------------------------------------------------------------------------------
/test/helpers/element_with_selectors_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ElementWithSelectorsTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should get visible text of an element, when selector is passed" do
8 | navigate_to "http://localhost:9090/page1.html"
9 | assert visible_text({:class, "example"}) == "Paragraph"
10 | end
11 |
12 | test "should raise when passed selector does not match any element" do
13 | navigate_to "http://localhost:9090/page1.html"
14 | assert_raise Hound.NoSuchElementError, fn ->
15 | visible_text({:class, "i-dont-exist"})
16 | end
17 | end
18 |
19 |
20 | test "should input value into field, when selector is passed" do
21 | navigate_to "http://localhost:9090/page1.html"
22 |
23 | element = {:name, "username"}
24 |
25 | input_into_field(element, "john")
26 | assert attribute_value(element, "value") == "john"
27 |
28 | input_into_field(element, "doe")
29 | assert attribute_value(element, "value") == "johndoe"
30 | end
31 |
32 |
33 | test "should fill a field with a value, when selector is passed" do
34 | navigate_to "http://localhost:9090/page1.html"
35 | element = {:name, "username"}
36 |
37 | fill_field(element, "johndoe")
38 | assert attribute_value(element, "value") == "johndoe"
39 |
40 | fill_field(element, "janedoe")
41 | assert attribute_value(element, "value") == "janedoe"
42 | end
43 |
44 |
45 | test "should get tag name of element, when selector is passed" do
46 | navigate_to "http://localhost:9090/page1.html"
47 | assert tag_name({:name, "username"}) == "input"
48 | end
49 |
50 |
51 | test "should clear field, when selector is passed" do
52 | navigate_to "http://localhost:9090/page1.html"
53 | element = {:name, "username"}
54 |
55 | fill_field(element, "johndoe")
56 | assert attribute_value(element, "value") == "johndoe"
57 |
58 | clear_field(element)
59 | assert attribute_value(element, "value") == ""
60 | end
61 |
62 |
63 | test "should return true if item is selected in a checkbox or radio, when selector is passed" do
64 | navigate_to "http://localhost:9090/page1.html"
65 | element = {:id, "speed-superpower"}
66 | click element
67 | assert selected?(element)
68 | end
69 |
70 |
71 | test "should return false if item is *not* selected, when selector is passed" do
72 | navigate_to "http://localhost:9090/page1.html"
73 | assert selected?({:id, "speed-flying"}) == false
74 | end
75 |
76 |
77 | test "Should return true if element is enabled, when selector is passed" do
78 | navigate_to "http://localhost:9090/page1.html"
79 | assert element_enabled?({:name, "username"}) == true
80 | end
81 |
82 |
83 | test "Should return false if element is *not* enabled, when selector is passed" do
84 | navigate_to "http://localhost:9090/page1.html"
85 | assert element_enabled?({:name, "promocode"}) == false
86 | end
87 |
88 |
89 | test "should get attribute value of an element, when selector is passed" do
90 | navigate_to "http://localhost:9090/page1.html"
91 | assert attribute_value({:class, "example"}, "data-greeting") == "hello"
92 | end
93 |
94 |
95 | test "should return true when an element has a class, when selector is passed" do
96 | navigate_to "http://localhost:9090/page1.html"
97 | assert has_class?({:class, "example"}, "example")
98 | assert has_class?({:class, "another_example"}, "another_class")
99 | end
100 |
101 |
102 | test "should return false when an element does not have a class, when selector is passed" do
103 | navigate_to "http://localhost:9090/page1.html"
104 | refute has_class?({:class, "example"}, "ex")
105 | refute has_class?({:class, "example"}, "other")
106 | end
107 |
108 |
109 | test "should return true if an element is displayed, when selector is passed" do
110 | navigate_to "http://localhost:9090/page1.html"
111 | assert element_displayed?({:class, "example"})
112 | end
113 |
114 |
115 | test "should return false if an element is *not* displayed, when selector is passed" do
116 | navigate_to "http://localhost:9090/page1.html"
117 | assert element_displayed?({:class, "hidden-element"}) == false
118 | end
119 |
120 |
121 | test "should get an element's location on screen, when selector is passed" do
122 | navigate_to "http://localhost:9090/page1.html"
123 | {loc_x, loc_y} = element_location({:class, "example"})
124 | assert is_integer(loc_x) || is_float(loc_x)
125 | assert is_integer(loc_y) || is_float(loc_y)
126 | end
127 |
128 |
129 | test "should get an element's size, when selector is passed" do
130 | navigate_to "http://localhost:9090/page1.html"
131 | size = element_size({:class, "example"})
132 | assert size == {400, 100}
133 | end
134 |
135 |
136 | test "should get css property of an element, when selector is passed" do
137 | navigate_to "http://localhost:9090/page1.html"
138 | assert css_property({:class, "container"}, "display") == "block"
139 | end
140 |
141 |
142 | test "should click on an element, when selector is passed" do
143 | navigate_to "http://localhost:9090/page1.html"
144 | click({:class, "submit-form"})
145 | assert current_url() == "http://localhost:9090/page2.html"
146 | end
147 |
148 |
149 | test "should submit a form element, when selector is passed" do
150 | navigate_to "http://localhost:9090/page1.html"
151 | submit_element({:name, "username"})
152 | Process.sleep(50)
153 | assert current_url() == "http://localhost:9090/page2.html"
154 | end
155 |
156 |
157 | test "should move mouse to an element" do
158 | navigate_to "http://localhost:9090/page1.html"
159 | move_to({:id, "mouse-actions"}, 5, 5)
160 | assert visible_text({:id, "mouse-actions"}) == "Mouse over"
161 | end
162 |
163 | test "should mouse down on an element" do
164 | navigate_to "http://localhost:9090/page1.html"
165 | move_to({:id, "mouse-actions"}, 5, 5)
166 | mouse_down()
167 | assert visible_text({:id, "mouse-actions"}) == "Mouse down"
168 | end
169 |
170 | test "should mouse up on an element" do
171 | navigate_to "http://localhost:9090/page1.html"
172 | move_to({:id, "mouse-actions"}, 5, 5)
173 | # Mouse up needs a mouse down before
174 | mouse_down()
175 | mouse_up()
176 | assert visible_text({:id, "mouse-actions"}) == "Mouse up"
177 | end
178 | end
179 |
--------------------------------------------------------------------------------
/test/helpers/log_test.exs:
--------------------------------------------------------------------------------
1 | defmodule LogTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "Should be able to extract log written in javascript" do
8 | navigate_to "http://localhost:9090/page1.html"
9 |
10 | execute_script("console.log(\"Some log\");")
11 | execute_script("console.log(\"Next log\");")
12 |
13 | if is_webdriver_selenium() do
14 | assert_raise Hound.NotSupportedError, "fetch_log() is not supported by driver selenium with browser firefox", fn ->
15 | fetch_log()
16 | end
17 | else
18 | log = fetch_log()
19 |
20 | assert log =~ "Some log"
21 | assert log =~ "Next log"
22 | end
23 | end
24 |
25 | test "Should be able to detect if theres any errors in the javascript" do
26 | navigate_to "http://localhost:9090/page_with_javascript_error.html"
27 | execute_script("console.log(\"Should not return normal logs\");")
28 |
29 | if is_webdriver_selenium() do
30 | assert_raise Hound.NotSupportedError, "fetch_errors() is not supported by driver selenium with browser firefox", fn ->
31 | fetch_errors()
32 | end
33 | else
34 | log = fetch_errors()
35 | refute log =~ "Should not return normal logs"
36 | assert log =~ "This is a javascript error"
37 | end
38 | end
39 |
40 | defp is_webdriver_selenium() do
41 | match?({:ok, %{driver: "selenium"}}, Hound.driver_info)
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/test/helpers/navigation_test.exs:
--------------------------------------------------------------------------------
1 | defmodule NavigationTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should get current url" do
8 | url = "http://localhost:9090/page1.html"
9 | navigate_to(url)
10 | assert url == current_url()
11 | end
12 |
13 | test "should get current path" do
14 | url = "http://localhost:9090/page1.html"
15 | navigate_to(url)
16 | assert current_path() == "/page1.html"
17 | end
18 |
19 | test "should navigate to a url" do
20 | url = "http://localhost:9090/page1.html"
21 |
22 | navigate_to(url)
23 | assert( url == current_url() )
24 | end
25 |
26 |
27 | test "should navigate to a relative url" do
28 | url = "http://localhost:9090/page1.html"
29 |
30 | navigate_to("/page1.html")
31 | assert url == current_url()
32 | end
33 |
34 | test "should navigate backward, forward and refresh" do
35 | url1 = "http://localhost:9090/page1.html"
36 | url2 = "http://localhost:9090/page2.html"
37 |
38 | navigate_to(url1)
39 | assert( url1 == current_url() )
40 |
41 | navigate_to(url2)
42 | assert( url2 == current_url() )
43 |
44 | navigate_back()
45 | assert( url1 == current_url() )
46 |
47 | navigate_forward()
48 | assert( url2 == current_url() )
49 |
50 | refresh_page()
51 | assert( url2 == current_url() )
52 | end
53 |
54 | end
55 |
--------------------------------------------------------------------------------
/test/helpers/orientation_test.exs:
--------------------------------------------------------------------------------
1 | defmodule OrientationTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | # hound_session()
6 |
7 | # test "should get current orientation" do
8 | # end
9 |
10 |
11 | # test "should set orientation" do
12 | # end
13 |
14 | end
15 |
--------------------------------------------------------------------------------
/test/helpers/page_test.exs:
--------------------------------------------------------------------------------
1 | defmodule PageTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | alias Hound.Element
6 |
7 | hound_session()
8 |
9 | test "should get page source" do
10 | navigate_to("http://localhost:9090/page1.html")
11 | assert(Regex.match?(~r//, page_source()))
12 | end
13 |
14 | test "should get visible page text" do
15 | navigate_to("http://localhost:9090/page1.html")
16 | assert(String.contains? visible_page_text(), "Flying")
17 | assert(not String.contains? visible_page_text(), "This is hidden")
18 | end
19 |
20 |
21 | test "should get page title" do
22 | navigate_to("http://localhost:9090/page1.html")
23 | assert("Hound Test Page" == page_title())
24 | end
25 |
26 |
27 | test "should get page title encoded with utf8" do
28 | navigate_to("http://localhost:9090/page_utf.html")
29 | assert("This is UTF: zażółć gęślą jaźń" == page_title())
30 | end
31 |
32 |
33 | test "should find element within page" do
34 | navigate_to("http://localhost:9090/page1.html")
35 | assert Element.element?(find_element(:css, ".example"))
36 | end
37 |
38 |
39 | test "search_element/3 should return {:error, :no_such_element} if element does not exist" do
40 | navigate_to("http://localhost:9090/page1.html")
41 | assert search_element(:css, ".i-dont-exist") == {:error, :no_such_element}
42 | end
43 |
44 | test "find_element/3 should raise NoSuchElementError if element does not exist" do
45 | navigate_to("http://localhost:9090/page1.html")
46 | assert_raise Hound.NoSuchElementError, fn ->
47 | find_element(:css, ".i-dont-exist")
48 | end
49 | end
50 |
51 | test "should find all elements within page" do
52 | navigate_to("http://localhost:9090/page1.html")
53 | elements = find_all_elements(:tag, "p")
54 | assert length(elements) == 6
55 | for element <- elements do
56 | assert Element.element?(element)
57 | end
58 | end
59 |
60 |
61 | test "should find a single element within another element" do
62 | navigate_to("http://localhost:9090/page1.html")
63 | container_id = find_element(:class, "container")
64 | element = find_within_element(container_id, :class, "example")
65 | assert Element.element?(element)
66 | end
67 |
68 | test "search_within_element/4 should return {:error, :no_such_element} if element is not found" do
69 | navigate_to("http://localhost:9090/page1.html")
70 | container_id = find_element(:class, "container")
71 | assert search_within_element(container_id, :class, "i-dont-exist") == {:error, :no_such_element}
72 | end
73 |
74 | test "find_within_element/4 should raise NoSuchElementError if element is not found" do
75 | navigate_to("http://localhost:9090/page1.html")
76 | container_id = find_element(:class, "container")
77 | assert_raise Hound.NoSuchElementError, fn -> find_within_element(container_id, :class, "i-dont-exist") end
78 | end
79 |
80 | test "should find all elements within another element" do
81 | navigate_to("http://localhost:9090/page1.html")
82 | container_id = find_element(:class, "container")
83 | elements = find_all_within_element(container_id, :tag, "p")
84 | assert length(elements) == 2
85 | for element <- elements do
86 | assert Element.element?(element)
87 | end
88 | end
89 |
90 |
91 | test "should get element in focus" do
92 | navigate_to("http://localhost:9090/page1.html")
93 | assert Element.element?(element_in_focus())
94 | end
95 |
96 |
97 | test "should send text to active element" do
98 | navigate_to("http://localhost:9090/page1.html")
99 | click {:name, "username"}
100 | send_text "test"
101 | send_text "123"
102 |
103 | assert attribute_value({:name, "username"}, "value") == "test123"
104 | end
105 |
106 | end
107 |
--------------------------------------------------------------------------------
/test/helpers/save_page_test.exs:
--------------------------------------------------------------------------------
1 | defmodule SavePageTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should save the page" do
8 | navigate_to("http://localhost:9090/page1.html")
9 | path = save_page("screenshot-test.html")
10 | assert File.exists?(path)
11 | end
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/test/helpers/screenshot_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ScreenshotTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should take a screenshot" do
8 | navigate_to("http://localhost:9090/page1.html")
9 | path = take_screenshot("screenshot-test.png")
10 | assert File.exists?(path)
11 | end
12 |
13 | end
14 |
--------------------------------------------------------------------------------
/test/helpers/script_execution_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ScriptExecutionTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "Execute javascript synchronously" do
8 | navigate_to "http://localhost:9090/page1.html"
9 | assert execute_script("return(arguments[0] + arguments[1]);", [1, 2]) == 3
10 | end
11 |
12 |
13 | test "Execute javascript asynchronously" do
14 | navigate_to "http://localhost:9090/page1.html"
15 | assert execute_script_async("arguments[arguments.length-1]('hello')", []) == "hello"
16 | end
17 |
18 |
19 | test "Pass element to javascript" do
20 | navigate_to "http://localhost:9090/page1.html"
21 | element = find_element(:id, "speed-flying")
22 | assert execute_script("return(arguments[0].value);", [element]) == "flying"
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/test/helpers/window_test.exs:
--------------------------------------------------------------------------------
1 | defmodule WindowTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should set and get the window size" do
8 | set_window_size current_window_handle(), 600, 400
9 | {width, height} = window_size(current_window_handle())
10 | assert width == 600
11 | assert height == 400
12 | end
13 |
14 |
15 | test "should maximize the window" do
16 | set_window_size current_window_handle(), 0, 0
17 | {width, height} = window_size(current_window_handle())
18 | assert width > 0
19 | assert height > 0
20 | end
21 |
22 |
23 | test "switch to a frame" do
24 | navigate_to "http://localhost:9090/page1.html"
25 | assert length(find_all_elements :class, "child-para") == 0
26 |
27 | focus_frame(0)
28 | assert length(find_all_elements :class, "child-para") > 0
29 | end
30 |
31 | test "focus window" do
32 | navigate_to "http://localhost:9090/page1.html"
33 | assert Enum.count(window_handles()) == 1
34 | execute_script("window.open('http://localhost:9090/page2.html')", [])
35 | assert Enum.count(window_handles()) == 2
36 | window_handles() |> Enum.at(1) |> focus_window()
37 | assert current_url() == "http://localhost:9090/page2.html"
38 | window_handles() |> Enum.at(0) |> focus_window()
39 | assert current_url() == "http://localhost:9090/page1.html"
40 | end
41 |
42 | test "close window" do
43 | navigate_to "http://localhost:9090/page1.html"
44 | assert Enum.count(window_handles()) == 1
45 | execute_script("window.open('http://localhost:9090/page2.html')", [])
46 | assert Enum.count(window_handles()) == 2
47 | window_handles() |> Enum.at(1) |> focus_window()
48 | close_current_window()
49 | window_handles() |> Enum.at(0) |> focus_window()
50 | assert Enum.count(window_handles()) == 1
51 | assert current_url() == "http://localhost:9090/page1.html"
52 | end
53 |
54 | if Hound.InternalHelpers.driver_supports?("focus_parent_frame") do
55 | test "switch to a frame and switch back to parent frame" do
56 | navigate_to "http://localhost:9090/page1.html"
57 | assert length(find_all_elements :class, "child-para") == 0
58 |
59 | focus_frame(0)
60 | assert length(find_all_elements :class, "child-para") > 0
61 |
62 | focus_parent_frame()
63 | assert length(find_all_elements :class, "child-para") == 0
64 | end
65 | end
66 | end
67 |
--------------------------------------------------------------------------------
/test/hound_test.exs:
--------------------------------------------------------------------------------
1 | defmodule HoundTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | setup do
6 | Hound.start_session
7 | parent = self()
8 | on_exit fn-> Hound.end_session(parent) end
9 | :ok
10 | end
11 |
12 | test "should return driver info" do
13 | {:ok, driver_info} = Hound.driver_info
14 | assert driver_info[:driver_type] == nil
15 | end
16 |
17 |
18 | test "should return the current session ID" do
19 | assert is_binary(Hound.current_session_id)
20 | end
21 |
22 |
23 | test "Should destroy all sessions for current process" do
24 | Hound.end_session
25 | assert Hound.SessionServer.all_sessions_for_pid(self()) == %{}
26 | end
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/test/matchers.exs:
--------------------------------------------------------------------------------
1 | defmodule MatcherTests do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | #visible_text_in_page?
8 | test "should return true when text is visible" do
9 | navigate_to "http://localhost:9090/page1.html"
10 | assert visible_in_page?(~r/Paragraph/)
11 | end
12 |
13 |
14 | test "should return true when text is loaded by javascript" do
15 | navigate_to "http://localhost:9090/page1.html"
16 | :timer.sleep(1000)
17 | assert visible_in_page?(~r/Javascript/)
18 | end
19 |
20 |
21 | test "should return false when text is *not* visible" do
22 | navigate_to "http://localhost:9090/page1.html"
23 | assert visible_in_page?(~r/hidden/) == false
24 | end
25 |
26 |
27 | # visible_text_in_element?
28 | test "should return true when text is visible inside block" do
29 | navigate_to "http://localhost:9090/page1.html"
30 | assert visible_in_element?({:class, "container"}, ~r/Another Paragraph/)
31 | end
32 |
33 |
34 | test "should return true when text is loaded by javascript inside block" do
35 | navigate_to "http://localhost:9090/page1.html"
36 | :timer.sleep(1000)
37 | assert visible_in_element?({:id, "javascript"}, ~r/Javascript/)
38 | end
39 |
40 | test "should return false when text is *not* visible inside element" do
41 | navigate_to "http://localhost:9090/page1.html"
42 | assert visible_in_element?({:class, "hidden-wrapper"}, ~r/hidden/) == false
43 | end
44 |
45 |
46 | test "should return true if element is present" do
47 | navigate_to "http://localhost:9090/page1.html"
48 | assert element?(:css, ".container")
49 | end
50 |
51 |
52 | test "should return false if element is *not* present" do
53 | navigate_to "http://localhost:9090/page1.html"
54 | assert element?(:css, ".contra") == false
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/test/metadata_test.exs:
--------------------------------------------------------------------------------
1 | defmodule Hound.MetadataTest do
2 | use ExUnit.Case
3 |
4 | use Hound.Helpers
5 |
6 | alias Hound.Metadata
7 |
8 | @ua "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"
9 |
10 | test "format produces UA compatible string" do
11 | assert Metadata.format(%{foo: "foo", bar: "baz"}) =~ ~r{BeamMetadata \([a-zA-Z0-9=-_]+\)}
12 | end
13 |
14 | test "extract returns empty map when no match" do
15 | assert Metadata.extract(@ua) == %{}
16 | end
17 |
18 | test "extract raises when data cannot be parsed" do
19 | assert_raise ArgumentError, fn ->
20 | Metadata.extract("#{@ua}/BeamMetadata (some random string)")
21 | end
22 |
23 | assert_raise Hound.InvalidMetadataError, fn ->
24 | bad_data = {:v123, "foobar"} |> :erlang.term_to_binary |> Base.encode64
25 | Metadata.extract("#{@ua}/BeamMetadata (#{bad_data})")
26 | end
27 | end
28 |
29 | test "extract returns metadata" do
30 | ua = Metadata.append(@ua, %{foo: "bar", baz: "qux"})
31 | assert Metadata.extract(ua) == %{foo: "bar", baz: "qux"}
32 | end
33 |
34 | test "accepts complex values" do
35 | metadata = %{ref: make_ref(), pid: self(), list: [1, 2, 3]}
36 | assert Metadata.extract(Metadata.append(@ua, metadata)) == metadata
37 | end
38 |
39 | test "metadata is passed to the browser through user agent" do
40 | metadata = %{my_pid: self()}
41 | Hound.start_session(metadata: metadata)
42 | navigate_to "http://localhost:9090/page1.html"
43 | ua = execute_script("return navigator.userAgent;", [])
44 | assert Metadata.extract(ua) == metadata
45 | Hound.end_session
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/test/multiple_browser_session_test.exs:
--------------------------------------------------------------------------------
1 | defmodule MultipleBrowserSessionTest do
2 | use ExUnit.Case
3 | use Hound.Helpers
4 |
5 | hound_session()
6 |
7 | test "should be able to run multiple sessions" do
8 | url1 = "http://localhost:9090/page1.html"
9 | url2 = "http://localhost:9090/page2.html"
10 |
11 | # Navigate to a url
12 | navigate_to(url1)
13 |
14 | # Change to another session
15 | change_session_to :another_session
16 | # Navigate to a url in the second session
17 | navigate_to(url2)
18 | # Then assert url
19 | assert url2 == current_url()
20 |
21 | # Now go back to the default session
22 | change_to_default_session()
23 | # Assert if the url is the one we visited
24 | assert url1 == current_url()
25 | end
26 |
27 | test "should be able to run multiple sessions using in_browser_session" do
28 | url1 = "http://localhost:9090/page1.html"
29 | url2 = "http://localhost:9090/page2.html"
30 |
31 | # Navigate to a url
32 | navigate_to(url1)
33 |
34 | # In another session...
35 | in_browser_session :another_session, fn->
36 | navigate_to(url2)
37 | assert url2 == current_url()
38 | end
39 |
40 | # Assert if the url is the one we visited
41 | assert url1 == current_url()
42 | end
43 |
44 | test "should preserve session after using in_browser_session" do
45 | url1 = "http://localhost:9090/page1.html"
46 | url2 = "http://localhost:9090/page2.html"
47 | url3 = "http://localhost:9090/page3.html"
48 |
49 | # Navigate to url1 in default session
50 | navigate_to(url1)
51 |
52 | # Change to a second session and navigate to url2
53 | change_session_to :session_a
54 | navigate_to(url2)
55 |
56 | # In a third session...
57 | in_browser_session :session_b, fn ->
58 | navigate_to(url3)
59 | assert url3 == current_url()
60 | end
61 |
62 | # Assert the current url is the url we visited in :session_a
63 | assert url2 == current_url()
64 |
65 | # Switch back to the default session
66 | change_session_to :default
67 |
68 | # Assert the current url is the one we visited in the default session
69 | assert url1 == current_url()
70 | end
71 |
72 | test "in_browser_session should return the result of the given function" do
73 | url1 = "http://localhost:9090/page1.html"
74 |
75 | # In another session, navigate to url1 and return the current url
76 | result =
77 | in_browser_session :another_session, fn ->
78 | navigate_to(url1)
79 | current_url()
80 | end
81 |
82 | assert result == url1
83 | end
84 | end
85 |
--------------------------------------------------------------------------------
/test/response_parser_test.exs:
--------------------------------------------------------------------------------
1 | defmodule ResponseParserTest do
2 | use ExUnit.Case
3 |
4 | alias Hound.ResponseParser
5 |
6 | defmodule DummyParser do
7 | use Hound.ResponseParser
8 | end
9 |
10 | defmodule DummyCustomErrorParser do
11 | use Hound.ResponseParser
12 |
13 | def handle_error(%{"message" => "some error"}) do
14 | "custom handler"
15 | end
16 | end
17 |
18 | test "parse/2" do
19 | body = ~s({"sessionId": 1})
20 | assert ResponseParser.parse(DummyParser, "session", 200, [], body) == {:ok, 1}
21 | end
22 |
23 | test "parse/2 with 204 no-content response" do
24 | assert ResponseParser.parse(DummyParser, "session", 204, [], "") == :ok
25 | end
26 |
27 | test "handle_response/3 session" do
28 | assert DummyParser.handle_response("session", 200, %{"sessionId" => 1}) == {:ok, 1}
29 | assert DummyParser.handle_response("session", 400, %{"sessionId" => 1}) == :error
30 | end
31 |
32 | test "handle_response/3 errors" do
33 | body = %{"value" => %{"message" => "error"}}
34 | assert DummyParser.handle_response("foo", 200, body) == {:error, "error"}
35 | body = %{"value" => %{"message" => "some error"}}
36 | assert DummyCustomErrorParser.handle_response("foo", 200, body) == "custom handler"
37 | body = %{"value" => %{"message" => "other error"}}
38 | assert DummyCustomErrorParser.handle_response("foo", 200, body) == {:error, "other error"}
39 | end
40 |
41 | test "handle_response/3 value" do
42 | assert DummyParser.handle_response("foo", 200, %{"status" => 0, "value" => "value"}) == "value"
43 | end
44 |
45 | test "handle_response/3 success" do
46 | assert DummyParser.handle_response("foo", 200, "whatever") == :ok
47 | end
48 |
49 | test "handle_response/3 error" do
50 | assert DummyParser.handle_response("foo", 500, "whatever") == :error
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/test/sample_pages/iframe.html:
--------------------------------------------------------------------------------
1 | This text is within a frame
2 |
--------------------------------------------------------------------------------
/test/sample_pages/page1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hound Test Page
5 |
19 |
20 |
21 |
22 |
Paragraph
23 |
Another Paragraph
24 |
25 |
26 | This is hidden
27 |
28 | Out of container paragraph
29 |
30 |
49 |
50 |
51 |
54 |
55 |
56 | I need action
57 |
58 |
59 |
60 |
61 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/test/sample_pages/page2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hound Another Test Page
5 |
6 |
7 | Paragraph
8 |
9 |
--------------------------------------------------------------------------------
/test/sample_pages/page3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hound Yet Another Test Page
5 |
6 |
7 | Paragraph
8 |
9 |
10 |
--------------------------------------------------------------------------------
/test/sample_pages/page_utf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | This is UTF: zażółć gęślą jaźń
6 |
7 |
8 | This is UTF: zażółć gęślą jaźń
9 |
10 |
11 |
--------------------------------------------------------------------------------
/test/sample_pages/page_with_javascript_error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hound Test Page
5 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/session_test.exs:
--------------------------------------------------------------------------------
1 | defmodule Hound.SessionTest do
2 | use ExUnit.Case
3 |
4 | alias Hound.Session
5 |
6 | test "make_capabilities uses default browser" do
7 | assert %{browserName: "chrome"} = Session.make_capabilities("chrome")
8 | end
9 |
10 | test "make_capabilities has default settings" do
11 | assert %{takesScreenshot: true} = Session.make_capabilities("chrome")
12 | end
13 |
14 | test "make_capabilities allows browser override" do
15 | assert %{browserName: "firefox"} = Session.make_capabilities("chrome", browser: "firefox")
16 | end
17 |
18 | test "make_capabilities uses driver overrides" do
19 | assert %{foo: "bar"} = Session.make_capabilities("chrome", driver: %{foo: "bar"})
20 | end
21 |
22 | test "make_capabilities overrides user agent" do
23 | ua = Hound.Browser.user_agent(:chrome)
24 | result = Session.make_capabilities("chrome", user_agent: ua)
25 | assert %{chromeOptions: %{"args" => ["--user-agent=" <> ^ua]}} = result
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/test/test_helper.exs:
--------------------------------------------------------------------------------
1 | Application.start :inets
2 |
3 | server_root = '#{Path.absname("test/sample_pages")}'
4 | test_server_config = [
5 | port: 9090,
6 | server_name: 'hound_test_server',
7 | server_root: server_root,
8 | document_root: server_root,
9 | bind_address: {127, 0, 0, 1}
10 | ]
11 |
12 | {:ok, pid} = :inets.start(:httpd, test_server_config)
13 |
14 | IO.puts "Stopping Hound and restarting with options for test suite..."
15 | :ok = Application.stop(:hound)
16 | Hound.Supervisor.start_link(
17 | driver: System.get_env("WEBDRIVER"),
18 | app_port: 9090
19 | )
20 |
21 | System.at_exit fn(_exit_status) ->
22 | :ok = :inets.stop(:httpd, pid)
23 | end
24 |
25 | ExUnit.start [max_cases: 5]
26 |
--------------------------------------------------------------------------------
/test/tools/start_webdriver.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ "$WEBDRIVER" = "phantomjs" ]; then
4 | npm install -g phantomjs
5 | nohup phantomjs -w &
6 | echo "Running with PhantomJs..."
7 | sleep 3
8 | elif [ "$WEBDRIVER" = "selenium" ]; then
9 | mkdir -p $HOME/src
10 | wget https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar
11 | nohup java -jar selenium-server-standalone-3.141.59.jar &
12 | echo "Running with Selenium..."
13 | sleep 10
14 | fi
15 |
--------------------------------------------------------------------------------