PhoenixIntegration.Requests (phoenix_integration v0.9.2) View Source
A set of functions intended to compliment the regular Phoenix.ConnTest utilities
of get
, post
, put
, patch
, and delete
.
Each request function takes a conn and a set of data telling it what to do. Then it requests one or more paths from your phoenix application, transforming the conn each time. The final conn is returned.
All the functions except follow_path
and follow_redirect
examine the html
content of the incoming conn to find a link or form to use. In this way, you
can both confirm that content exists in rendered pages and take actions as
the user would.
This is intended to be used as a (possibly long) chain of piped functions that exercises a set of functionality in your application.
Examples
test "Basic page flow", %{conn: conn} do
# get the root index page
get( conn, page_path(conn, :index) )
# click/follow through the various about pages
|> follow_link( "About Us" )
|> follow_link( "Contact" )
|> follow_link( "Privacy" )
|> follow_link( "Terms of Service" )
|> follow_link( "Home" )
|> assert_response( status: 200, path: page_path(conn, :index) )
end
test "Create new user", %{conn: conn} do
# get the root index page
get( conn, page_path(conn, :index) )
# create the new user
|> follow_link( "Sign Up" )
|> follow_form( %{ user: %{
name: "New User",
email: "user@example.com",
password: "test.password",
confirm_password: "test.password"
}} )
|> assert_response(
status: 200,
path: page_path(conn, :index),
html: "New User" )
end
Link to this section Summary
Functions
Finds a button in conn.resp_body and acts as if the user had clicked on it, and returns the resulting conn.
Finds a link in conn.resp_body, requests it as if the user had clicked on it, and returns the resulting conn.
Convenience function to find and return a form in a conn.resp_body.
Finds a button in conn.resp_body, acts as if the user had clicked on it, follows any redirects, and returns the resulting conn.
Calls a function and follows the any redirects in the returned conn
.
If the function returns anything other than a conn
, then the result is ignored
and follow_fn
will simply return the original conn
Finds a form in conn.resp_body, fills out the fields with the given data, requests the form's action, follows any redirects and returns the resulting conn.
Finds a link in conn.resp_body, requests it as if the user had clicked on it, follows any redirects, and returns the resulting conn.
Similar to a standard get/post/put/patch/delete call in a ConnTest except that
follow_path
follows any redirects returned in the conn's response header.
Given a conn who's response is a redirect, follow_redirect
calls the path indicated
by the "location" response header and returns the conn from that call.
Finds a form in conn.resp_body, fills out the fields with the given data, requests the form's action and returns the resulting conn.
Link to this section Functions
Finds a button in conn.resp_body and acts as if the user had clicked on it, and returns the resulting conn.
This is very similar to click_link
except that it looks for button tags
as rendered by PhoenixHtml.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.identifier
indicates which link to find in the html. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
opts
A map of additional options:method
- method to use when requesting the path. Defaults to"get"
;
click_button
does not follow any redirects returned by the request. This allows
you to explicitly check that the redirect is correct. Use follow_redirect
to request
the location redirected to, or just use follow_link
to do it in one call.
If the link is not found in the body, click_button
raises an error.
Examples:
# click a link specified by path or uri
get( conn, thing_path(conn, :index) )
|> click_button( page_path(conn, :index) )
# click a link specified by html id with a non-get method
get( conn, thing_path(conn, :index) )
|> click_button( "#button_id", method: :delete )
# click a link containing the given text
get( conn, thing_path(conn, :index) )
|> click_button( "Settings" )
# test a redirect and continue
get( conn, thing_path(conn, :index) )
|> click_button( "something that redirects to new" )
|> assert_response( status: 302, to: think_path(conn, :new) )
|> follow_redirect()
|> assert_response( status: 200, path: think_path(conn, :new) )
Returns the transformed conn after submitting the request.
Button request methods that don't use the :get method
Unlike trying to click anchor tags, Phoenix always puts the method in button tags as an attribute.
This means that if you want to match agains tags with a non-get method you can, but you don't really need to.
Finds a link in conn.resp_body, requests it as if the user had clicked on it, and returns the resulting conn.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.identifier
indicates which link to find in the html. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
opts
A map of additional options:method
- method to use when requesting the path. Defaults to"get"
;
click_link
does not follow any redirects returned by the request. This allows
you to explicitly check that the redirect is correct. Use follow_redirect
to request
the location redirected to, or just use follow_link
to do it in one call.
If the link is not found in the body, click_link
raises an error.
Examples:
# click a link specified by path or uri
get( conn, thing_path(conn, :index) )
|> click_link( page_path(conn, :index) )
# click a link specified by html id with a non-get method
get( conn, thing_path(conn, :index) )
|> click_link( "#link-id", method: :delete )
# click a link containing the given text
get( conn, thing_path(conn, :index) )
|> click_link( "Settings" )
# test a redirect and continue
get( conn, thing_path(conn, :index) )
|> click_link( "something that redirects to new" )
|> assert_response( status: 302, to: think_path(conn, :new) )
|> follow_redirect()
|> assert_response( status: 200, path: think_path(conn, :new) )
Links that don't use the :get method
When Phoenix.Html renders a link, it usually generates an <a>
tag. However, if you
specify a method other than :get, then Phoenix generates html looks like a link, but
is really a form using the method. This is why you must specify the method used in opts
if you used anything other than the standard :get in your link.
# follow a non-get link
click_link( conn, thing_path(conn, :delete), method: :delete )
Convenience function to find and return a form in a conn.resp_body.
Returns the form as a map.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.opts
A map of additional optionsidentifier
indicates which link to find in the html. Defaults tonil
. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
:method
- restricts the forms searched to those whose action uses the given method (such as "post" or "put"). Defaults tonil
;:finder
- finding string passed toFloki.find
. Defaults to"form"
If no opts.identifier
is specified, the first form that makes sense is used. Unless you
have multiple forms on your page, this often is the most understandable pattern.
If no appropriate form is found, fetch_form
raises an error.
If you have more than one form in the response, you will probably need to use the identifier options similar to what how you specify a form for submit_form or follow_form.
Example:
# get the value from a form on the page.
fetch_form( conn )
## returns something like...
%{
id: "some_id",
method: "put",
action: "/some/action"
inputs: %{
user: %{
first_name: "Jane",
last_name: "Doe"
}
}
}
Note: this fetches the form as it is in the response. It will not show you updates you are making as you prepare for the next submission.
In HTML, tags without values are not sent to the controller. For
your convenience, this function shows you that valueless tags are in the
form, marking them with :no_value
. Note that some tags have values
even if there's no value
or checked
attribute. For example, a
text input's default value is the empty string.
Finds a button in conn.resp_body, acts as if the user had clicked on it, follows any redirects, and returns the resulting conn.
This is very similar to follow_link
except that it looks for button tags
as rendered by PhoenixHtml.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.identifier
indicates which link to find in the html. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
opts
A map of additional options:method
- method to use when requesting the path. Defaults to"get"
;:max_redirects
- Maximum number of redirects to follow. Defaults to5
;
If the link is not found in the body, follow_button
raises an error.
Example:
# click through several pages that should point to each other
get( conn, thing_path(conn, :index) )
|> follow_button( "#settings_button" )
|> follow_button( "Cancel" )
|> assert_response( path: thing_path(conn, :index) )
Button request methods that don't use the :get method
Returns the transformed conn after submitting, then following the request.
Unlike trying to follow anchor tags, Phoenix always puts the method in button tags as an attribute.
This means that if you want to match agains tags with a non-get method you can, but you don't really need to.
Calls a function and follows the any redirects in the returned conn
.
If the function returns anything other than a conn
, then the result is ignored
and follow_fn
will simply return the original conn
This gives a way to insert custom assertions, or other setup code without breaking the piped chain of functions.
Parameters
conn
A conn that has been set up to work in the test environment. Could be the conn originally passed in to the test;func
a function in the form offn(conn) -> end
;opts
A map of additional options:max_redirects
- Maximum number of redirects to follow. Defaults to5
;
Example:
follow_fn( conn, fn(c) ->
"/some_path/" <> token = c.request_path
assert token == "valid_token"
end)
Finds a form in conn.resp_body, fills out the fields with the given data, requests the form's action, follows any redirects and returns the resulting conn.
Similar to submit_form
, except that it does follow redirects.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.fields
is a map of fields and data to be written into the form before submitting its action. The data can take one of three forms:- Most frequently, it's a string.
- It can be a list of strings. That's used when a set of tags in the form have names ending with
[]
to tell Phoenix to create a list value. See the example below. - It can be an Elixir struct like
DateTime
. In that case, the fields within the struct are used to find matching tags (by name) in the form. Fields that don't match are ignored. See the example below. - If you use
Plug.Upload
, you can set aninput type="file"
value to the%Plug.Upload{}
value you'd expect Phoenix to deliver to your controller action. See the example below.
opts
A map of additional optionsidentifier
indicates which link to find in the html. Defaults tonil
. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
:method
- restricts the forms searched to those whose action uses the given method (such as "post" or "put"). Defaults tonil
;:finder
- finding string passed toFloki.find
. Defaults to"form"
If no opts.identifier
is specified, the first form that makes sense is used. Unless you
have multiple forms on your page, this often is the most understandable pattern.
If no appropriate form is found, follow_form
raises an error.
Example:
upload = %Plug.Upload{
content_type: "image/jpg",
path: "/var/mytests/photo.jpg",
filename: "photo.jpg"}
# fill out a form and submit it
get( conn, thing_path(conn, :edit, thing) )
|> follow_form( %{ thing: %{
name: "Updated Name",
expires: ~D[2011-09-23],
some_count: 42,
comments: ["first", "second"],
photo: upload
}})
|> assert_response( status: 200, path: thing_path(conn, :show, thing) )
In this example, the form would contain list-creating HTML like this:
<input id="comment1" type="text" name="thing[comments][]" value="">
<input id="comment2" type="text" name="thing[comments][]" value="">
As it happens, the form has tags for only the month and year of the expiration date:
<select name="thing[expires][year]"> ... </select>
<select name="thing[expires][month]"> ... </select>
... so the day part of the Date
is ignored.
The photo part of the form might have been created like this:
<%= file_input f, :photo %>
Finds a link in conn.resp_body, requests it as if the user had clicked on it, follows any redirects, and returns the resulting conn.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.identifier
indicates which link to find in the html. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
opts
A map of additional options:method
- method to use when requesting the path. Defaults to"get"
;:max_redirects
- Maximum number of redirects to follow. Defaults to5
;
This is similar to click_link
, except that it follows returned redirects. This
is very useful during integration tests as you typically want to emulate what the
user is really doing. You will probably use follow_link
more than click_link
.
If the link is not found in the body, follow_link
raises an error.
Example:
# click through several pages that should point to each other
get( conn, thing_path(conn, :index) )
|> follow_link( "#settings" )
|> follow_link( "Cancel" )
|> assert_response( path: thing_path(conn, :index) )
Links that don't use the :get method
When Phoneix.Html renders a link, it usually generates an <a>
tag. However, if you
specify a method other than :get, then Phoenix generates html looks like a link, but
is really a form using the method. This is why you must specify the method used in opts
if you used anything other than the standard :get in your link.
# follow a non-get link
follow_link( conn, thing_path(conn, :delete), method: :delete )
Similar to a standard get/post/put/patch/delete call in a ConnTest except that
follow_path
follows any redirects returned in the conn's response header.
Unlike the rest of the functions in this module, follow_path
ignores the
conn.resp_body and simply uses the given path.
Parameters
conn
A conn that has been set up to work in the test environment. Could be the conn originally passed in to the test;path
A path that works with your router;opts
A map of additional options:method
- method to use when requesting the path. Defaults to"get"
;:max_redirects
- Maximum number of redirects to follow. Defaults to5
;
Example:
follow_path( conn, thing_path(conn, :index) )
|> assert_response( status: 200, path: think_path(conn, :index) )
Given a conn who's response is a redirect, follow_redirect
calls the path indicated
by the "location" response header and returns the conn from that call.
Parameters
conn
A conn whose status 302, which is a redirect. The conn's location header should point to the path being redirected to.max_redirects
The maximum number of recirects to follow. Defaults to5
;
Any incoming conn.status
other than 302 causes follow_redirect
to take no
action and return the incoming conn for further processing.
Finds a form in conn.resp_body, fills out the fields with the given data, requests the form's action and returns the resulting conn.
Parameters
conn
should be a conn returned from a previous request that rendered some html. The functions are designed to pass the conn from one call into the next via pipes.fields
a map of fields and data to be written into the form before submitting its action.opts
A map of additional optionsidentifier
indicates which link to find in the html. Defaults tonil
. Valid values can be in the following forms:"/some/path"
specify the link's href starting with a"/"
character"http://www.example.com/some/uri"
, specify the href as full uri starting with either"http"
or"https"
"#element-id"
specify the html element id of the link you are looking for. Must start start with the"#"
character (same as css id specifier)."Some Text"
specify text contained within the link you are looking for.
:method
- restricts the forms searched to those whose action uses the given method (such as "post" or "put"). Defaults tonil
;:finder
- finding string passed toFloki.find
. Defaults to"form"
If no opts.identifier
is specified, the first form that makes sense is used. Unless you
have multiple forms on your page, this often is the most understandable pattern.
If no appropriate form is found, submit_form
raises an error.
Any redirects are not followed.
Example:
# fill out a form and submit it
get( conn, thing_path(conn, :edit, thing) )
|> submit_form( %{ thing: %{
name: "Updated Name",
some_count: 42
}})
|> assert_response( status: 302, to: thing_path(conn, :show, thing) )