assert_html

ExUnit assert helpers for testing rendered HTML.


Keywords
elixir, test, view
License
MIT

Documentation

AssertHTML

Build Status Hex pm Coverage Status

AssertHTML is an Elixir library for parsing and extracting data from HTML and XML with CSS. AssertHTML adds ExUnit assert helpers for testing rendered HTML using CSS selectors.

It is very useful in Phoenix Controller and Integration tests.

Usage

Usage in Phoenix Controller and Integration Test

Assuming the html_response(conn, 200) returns:

<!DOCTYPE html>
<html>
  <head>
    <title>PAGE TITLE</title>
  </head>
  <body>
    <a href="/signup">Sign up</a>
    <a href="/help">Help</a>
  </body>
</html>

An example controller test:

defmodule YourAppWeb.PageControllerTest do
  use YourAppWeb.ConnCase, async: true

  test "should get index", %{conn: conn} do
    conn = conn
    |> get(Routes.page_path(conn, :index))

    html_response(conn, 200)
    # Page title is "PAGE TITLE"
    |> assert_html("title", "PAGE TITLE")
    # Page title is "PAGE TITLE" and there is only one title element
    |> assert_html("title", count: 1, text: "PAGE TITLE")
    # Page title matches "PAGE" and there is only one title element
    |> assert_html("title", count: 1, match: "PAGE")
    # Page has one link with href value "/signup"
    |> assert_html("a[href='/signup']", count: 1)
    # Page has at least one link
    |> assert_html("a", min: 1)
    # Page has at most two links
    |> assert_html("a", max: 2)
    # Page contains no forms
    |> refute_html("form")
  end
end

Contains

assert_html(html, ~r{Hello World}) - match string in HTML
refute_html(html, ~r{Another World}) - should not contain string in HTML

 assert_html(html, ".content") do
   assert_html(~r{Hello World})
 end

CSS selectors

assert_html(html, ".css .selector") - check element exists in CSS selector path

refute_html(html, ".errors .error") - element not exists in path

Check attributes

assert_html(html, "form", class: "form", method: "post", action: "/session/login") do
  assert_html ".-email" do
    assert_html("label", text: "Email", for: "staticEmail", class: "col-form-label")
    assert_html("div input", type: "text", readonly: true, class: "form-control-plaintext", value: "email@example.com")
  end
  assert_html(".-password") do
    assert_html("label", text: "Password", for: "inputPassword")
    assert_html("div input", placeholder: "Password", type: "password", class: "form-control", id: "inputPassword", placeholder: "Password")
  end

  assert_html("button", type: "submit", class: "primary")
end

Example

defmodule ExampleControllerTest do
  use ExUnit.Case, async: true
  use AssertHTML

  test "shows search form", %{conn: conn} do
    conn_resp = get(conn, Routes.page_path(conn, :new))
    assert response = html_response(conn_resp, 200)

    assert_html response do
      # Check element exists in CSS selector path
      assert_html "p.description"

      # element doesn't exists
      refute_html ".flash-message"

      # assert form attributes
      assert_html "form.new_page", action: Routes.page_path(conn, :create), method: "post" do
        # assert elements inside the `form.new_page` selector
        assert_html "label", class: "form-label", text: "Page name"
        assert_html "input", type: "text", class: "form-control", value: "", name: "page_name"
        assert_html "button", class: "form-button", text: "Submit"
      end
    end
  end
end

Documentation can be found at https://hexdocs.pm/assert_html.

Installation

It's available in Hex, the package can be installed as:

Add assert_html to your list of dependencies in mix.exs:

def deps do
  [
    {:assert_html, ">= 0.0.1", only: :test}
  ]
end

Then run mix deps.get to get the package.

Contribution

Feel free to send your PR with proposals, improvements or corrections 😉.

License

This software is licensed under the MIT license.