Test views by writing expectations about Html
values.
import Html
import Html.Attributes exposing (class)
import Test exposing (test)
import Test.Html.Query as Query
import Test.Html.Selector exposing (text, tag)
test "Button has the expected text" <|
\() ->
Html.div [ class "container" ]
[ Html.button [] [ Html.text "I'm a button!" ] ]
|> Query.fromHtml
|> Query.find [ tag "button" ]
|> Query.has [ text "I'm a button!" ]
These tests are designed to be written in a pipeline like this:
- Call
Query.fromHtml
on yourHtml
to begin querying it. - Use queries like
Query.find
,Query.findAll
, andQuery.children
to find the elements to test. - Create expectations using things like
Query.has
andQuery.count
.
These are normal expectations, so you can use them with fuzz
just as easily as with test
!
Queries come in two flavors: Single
and Multiple
.
This is because some queries are expected to return a single result, whereas others may return multiple results.
If a Single
query finds exactly one result, it will succeed and continue with
any further querying or expectations. If it finds zero results, or more than one,
the test will fail.
Since other querying and expectation functions are written in terms of Single
and Multiple
, the compiler can help make sure queries are connected as
expected. For example, count
accepts a Multiple
, because counting a single element does not make much sense!
If you have a Multiple
and want to use an expectation that works on a Single
,
such as Query.has
, you can use Query.each
to run the expectation on each of the elements in the Multiple
.
Ordinary Html.Attribute msg
values can be used to select elements using
Test.Html.Selector.attribute
. It is important when using this selector to
understand its behavior.
-
Html.Attributes.class
andHtml.Attributes.classList
will work the same asTest.Html.Selector.classes
, matching any element with at least the given classes. This behavior echoes that ofelement.querySelectorAll('.my-class')
from JavaScript, where any element with at least.my-class
will match the query. -
Html.Attributes.style
will work the same way asTest.Html.Selector.styles
, matching any element with at least the given style properties. -
Any other
String
attributes and properties liketitle
, orBool
attributes likedisabled
will match elements with the exact value for those attributes. -
Any attributes from
Html.Events
, or attributes with values that have types other thanString
orBool
will not match anything.
The example below demonstrates usage
import Html
import Html.Attributes as Attr
import Test exposing (test, describe)
import Test.Html.Query as Query
import Test.Html.Selector exposing (attribute, text)
tests =
describe "attributes"
[ test "the welcome <h1> says hello!" <|
\() ->
Html.div [] [ Html.h1 [ Attr.title "greeting" ] [ Html.text "Hello!" ] ]
|> Query.fromHtml
|> Query.find [ attribute <| Attr.title "greeting" ]
|> Query.has [ text "Hello!" ]
, test "the .Hello.World div has the class Hello" <|
\() ->
Html.div
[ Attr.classList
[ ( True, "Hello" )
, ( True, "World" )
]
]
|> Query.fromHtml
|> Query.find
[ attribute <|
Attr.classList [ ( True, Hello ) ]
]
, test "the header is red" <|
\() ->
Html.header
[ Attr.style
[ ( "backround-color", "red" )
, ( "color", "yellow" )
]
]
|> Query.fromHtml
|> Query.find
[ attribute <|
Attr.style [ ( "backround-color", "red" ) ]
]
]
Version | Notes |
---|---|
5.1.2 | Fix bug with mapped and lazy views |
5.1.1 | Fix children |
5.1.0 | Add filtermap |
5.0.1 | Fix bug with lazy views |
5.0.0 | Allow querying by attributes |
4.1.0 | Query styles |
4.0.0 | Allow custom events |
3.0.0 | Allow events to be testable |
2.0.0 | Better support for events by @rogeriochaves |
1.1.0 | Support for events by @rogeriochaves |
1.0.0 | Initial release |